From 7799dac33c9c501f5850703e92cb79b8c7c28a75 Mon Sep 17 00:00:00 2001 From: Diego Nascimento Date: Fri, 26 Jul 2019 14:24:37 -0300 Subject: [PATCH 1/2] chore(senna): Bump version from 2.7.7 to 2.7.8 --- build/amd/senna/src/app/version-min.js | 2 +- build/amd/senna/src/app/version.js | 2 +- .../amd/senna/src/screen/RequestScreen-min.js | 2 +- build/amd/senna/src/screen/RequestScreen.js | 17 ++++++---- .../amd/senna/src/screen/RequestScreen.js.map | 2 +- build/globals/senna-debug.js | 33 ++++++++++++++----- build/globals/senna-min.js | 6 ++-- build/globals/senna.js | 33 ++++++++++++++----- build/globals/senna.js.map | 2 +- package.json | 2 +- 10 files changed, 68 insertions(+), 33 deletions(-) diff --git a/build/amd/senna/src/app/version-min.js b/build/amd/senna/src/app/version-min.js index a6cfef7..f0dc147 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.7";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.8";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 9ed8793..4526c2e 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.7'; + var version = '2.7.8'; exports.default = version; }); diff --git a/build/amd/senna/src/screen/RequestScreen-min.js b/build/amd/senna/src/screen/RequestScreen-min.js index 162b634..2b2de31 100644 --- a/build/amd/senna/src/screen/RequestScreen-min.js +++ b/build/amd/senna/src/screen/RequestScreen-min.js @@ -1 +1 @@ -define(["exports","metal/src/metal","metal-ajax/src/Ajax","metal-structs/src/all/structs","metal-promise/src/promise/Promise","../errors/errors","../utils/utils","../globals/globals","./Screen","metal-uri/src/Uri","metal-useragent/src/UA"],function(e,t,r,a,u,o,n,i,s,l,f){"use strict";function d(e){return e&&e.__esModule?e:{"default":e}}function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function p(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function h(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(e,"__esModule",{value:!0});var m=d(r),y=d(u),v=d(o),E=d(n),b=d(i),R=d(s),S=d(l),g=d(f),P=function(){function e(e,t){for(var r=0;r=200&&e<=399}},{key:"load",value:function(e){var u=this,o=this.getCache();if((0,t.isDefAndNotNull)(o))return y["default"].resolve(o);var n=null,i=this.httpMethod,s=new a.MultiMap;Object.keys(this.httpHeaders).forEach(function(e){return s.add(e,u.httpHeaders[e])}),b["default"].capturedFormElement&&(this.addSafariXHRPolyfill(),n=new FormData(b["default"].capturedFormElement),this.maybeAppendSubmitButtonValue_(n),i=r.POST,g["default"].isIeOrEdge&&s.add("If-None-Match",'"0"'));var l=this.formatLoadPath(e);return m["default"].request(l,i,n,s,null,this.timeout).then(function(e){return u.removeSafariXHRPolyfill(),u.setRequest(e),u.assertValidResponseStatusCode(e.status),i===r.GET&&u.isCacheable()&&u.addCache(e.responseText),e.requestPath=l,e.responseText})["catch"](function(e){switch(u.removeSafariXHRPolyfill(),e.message){case v["default"].REQUEST_TIMEOUT:e.timeout=!0;break;case v["default"].REQUEST_ERROR:e.requestError=!0;break;case v["default"].REQUEST_PREMATURE_TERMINATION:e.requestError=!0,e.requestPrematureTermination=!0}throw e})}},{key:"maybeAppendSubmitButtonValue_",value:function(e){var t=b["default"].capturedFormButtonElement;t&&t.name&&e.append(t.name,t.value)}},{key:"maybeExtractResponseUrlFromRequest",value:function(e){var t=e.responseURL;return t?t:e.getResponseHeader(r.X_REQUEST_URL_HEADER)}},{key:"addSafariXHRPolyfill",value:function(){if(b["default"].capturedFormElement&&g["default"].isSafari)for(var e=b["default"].capturedFormElement.querySelectorAll('input[type="file"]:not([disabled])'),t=0;t0)return;r.setAttribute("data-safari-temp-disabled","true"),r.setAttribute("disabled","")}}},{key:"removeSafariXHRPolyfill",value:function(){if(b["default"].capturedFormElement&&g["default"].isSafari)for(var e=b["default"].capturedFormElement.querySelectorAll('input[type="file"][data-safari-temp-disabled]'),t=0;t=200&&e<=399}},{key:"getFormData",value:function(e,t){var r=new FormData(e);return this.maybeAppendSubmitButtonValue_(r,t),r}},{key:"load",value:function(e){var u=this,o=this.getCache();if((0,t.isDefAndNotNull)(o))return y["default"].resolve(o);var n=null,i=this.httpMethod,s=new a.MultiMap;Object.keys(this.httpHeaders).forEach(function(e){return s.add(e,u.httpHeaders[e])}),b["default"].capturedFormElement&&(this.addSafariXHRPolyfill(),n=this.getFormData(b["default"].capturedFormElement,b["default"].capturedFormButtonElement),i=r.POST,g["default"].isIeOrEdge&&s.add("If-None-Match",'"0"'));var l=this.formatLoadPath(e);return m["default"].request(l,i,n,s,null,this.timeout).then(function(e){return u.removeSafariXHRPolyfill(),u.setRequest(e),u.assertValidResponseStatusCode(e.status),i===r.GET&&u.isCacheable()&&u.addCache(e.responseText),e.requestPath=l,e.responseText})["catch"](function(e){switch(u.removeSafariXHRPolyfill(),e.message){case v["default"].REQUEST_TIMEOUT:e.timeout=!0;break;case v["default"].REQUEST_ERROR:e.requestError=!0;break;case v["default"].REQUEST_PREMATURE_TERMINATION:e.requestError=!0,e.requestPrematureTermination=!0}throw e})}},{key:"maybeAppendSubmitButtonValue_",value:function(e,t){t&&t.name&&e.append(t.name,t.value)}},{key:"maybeExtractResponseUrlFromRequest",value:function(e){var t=e.responseURL;return t?t:e.getResponseHeader(r.X_REQUEST_URL_HEADER)}},{key:"addSafariXHRPolyfill",value:function(){if(b["default"].capturedFormElement&&g["default"].isSafari)for(var e=b["default"].capturedFormElement.querySelectorAll('input[type="file"]:not([disabled])'),t=0;t0)return;r.setAttribute("data-safari-temp-disabled","true"),r.setAttribute("disabled","")}}},{key:"removeSafariXHRPolyfill",value:function(){if(b["default"].capturedFormElement&&g["default"].isSafari)for(var e=b["default"].capturedFormElement.querySelectorAll('input[type="file"][data-safari-temp-disabled]'),t=0;t= 200 && statusCode <= 399; } + }, { + key: 'getFormData', + value: function getFormData(formElement, submittedButtonElement) { + var formData = new FormData(formElement); + this.maybeAppendSubmitButtonValue_(formData, submittedButtonElement); + return formData; + } }, { key: 'load', value: function load(path) { @@ -249,8 +256,7 @@ define(['exports', 'metal/src/metal', 'metal-ajax/src/Ajax', 'metal-structs/src/ }); if (_globals2.default.capturedFormElement) { this.addSafariXHRPolyfill(); - body = new FormData(_globals2.default.capturedFormElement); - this.maybeAppendSubmitButtonValue_(body); + body = this.getFormData(_globals2.default.capturedFormElement, _globals2.default.capturedFormButtonElement); httpMethod = RequestScreen.POST; if (_UA2.default.isIeOrEdge) { headers.add('If-None-Match', '"0"'); @@ -285,10 +291,9 @@ define(['exports', 'metal/src/metal', 'metal-ajax/src/Ajax', 'metal-structs/src/ } }, { key: 'maybeAppendSubmitButtonValue_', - value: function maybeAppendSubmitButtonValue_(body) { - var button = _globals2.default.capturedFormButtonElement; - if (button && button.name) { - body.append(button.name, button.value); + value: function maybeAppendSubmitButtonValue_(formData, submittedButtonElement) { + if (submittedButtonElement && submittedButtonElement.name) { + formData.append(submittedButtonElement.name, submittedButtonElement.value); } } }, { diff --git a/build/amd/senna/src/screen/RequestScreen.js.map b/build/amd/senna/src/screen/RequestScreen.js.map index 317b767..95e85fd 100644 --- a/build/amd/senna/src/screen/RequestScreen.js.map +++ b/build/amd/senna/src/screen/RequestScreen.js.map @@ -1 +1 @@ -{"version":3,"sources":["RequestScreen.js"],"names":["RequestScreen","cacheable","httpHeaders","httpMethod","GET","request","timeout","status","isValidResponseStatusCode","error","Error","INVALID_STATUS","invalidStatus","statusCode","path","redirectPath","getRequestPath","state","senna","form","uri","setHostname","window","location","hostname","setProtocol","protocol","port","setPort","isIeOrEdge","makeUnique","toString","getRequest","requestPath","responseUrl","maybeExtractResponseUrlFromRequest","removeUnique","getUrlPath","cache","getCache","resolve","body","headers","Object","keys","forEach","add","header","capturedFormElement","addSafariXHRPolyfill","FormData","maybeAppendSubmitButtonValue_","POST","formatLoadPath","then","removeSafariXHRPolyfill","setRequest","xhr","assertValidResponseStatusCode","isCacheable","addCache","responseText","catch","reason","message","REQUEST_TIMEOUT","REQUEST_ERROR","requestError","REQUEST_PREMATURE_TERMINATION","requestPrematureTermination","button","capturedFormButtonElement","name","append","value","responseURL","getResponseHeader","X_REQUEST_URL_HEADER","isSafari","inputs","querySelectorAll","index","length","input","files","setAttribute","removeAttribute","toLowerCase"],"mappings":"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","file":"src/screen/RequestScreen.js","sourcesContent":["'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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["RequestScreen.js"],"names":["RequestScreen","cacheable","httpHeaders","httpMethod","GET","request","timeout","status","isValidResponseStatusCode","error","Error","INVALID_STATUS","invalidStatus","statusCode","path","redirectPath","getRequestPath","state","senna","form","uri","setHostname","window","location","hostname","setProtocol","protocol","port","setPort","isIeOrEdge","makeUnique","toString","getRequest","requestPath","responseUrl","maybeExtractResponseUrlFromRequest","removeUnique","getUrlPath","formElement","submittedButtonElement","formData","FormData","maybeAppendSubmitButtonValue_","cache","getCache","resolve","body","headers","Object","keys","forEach","add","header","capturedFormElement","addSafariXHRPolyfill","getFormData","capturedFormButtonElement","POST","formatLoadPath","then","removeSafariXHRPolyfill","setRequest","xhr","assertValidResponseStatusCode","isCacheable","addCache","responseText","catch","reason","message","REQUEST_TIMEOUT","REQUEST_ERROR","requestError","REQUEST_PREMATURE_TERMINATION","requestPrematureTermination","name","append","value","responseURL","getResponseHeader","X_REQUEST_URL_HEADER","isSafari","inputs","querySelectorAll","index","length","input","files","setAttribute","removeAttribute","toLowerCase"],"mappings":"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","file":"src/screen/RequestScreen.js","sourcesContent":["'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 /**\n * Returns the form data\n * This method can be extended in order to have a custom implementation of the form params\n * @param {!Element} formElement\n * @param {!Element} submittedButtonElement\n * @return {!FormData}\n */\n\tgetFormData(formElement, submittedButtonElement) {\n let formData = new FormData(formElement);\n this.maybeAppendSubmitButtonValue_(formData, submittedButtonElement);\n return formData;\n }\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 = this.getFormData(globals.capturedFormElement, globals.capturedFormButtonElement);\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 * @param {!Element} submittedButtonElement\n * @protected\n\t */\n\tmaybeAppendSubmitButtonValue_(formData, submittedButtonElement) {\n\t\tif (submittedButtonElement && submittedButtonElement.name) {\n formData.append(submittedButtonElement.name, submittedButtonElement.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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/build/globals/senna-debug.js b/build/globals/senna-debug.js index 8b00dbf..3204e8d 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.7 + * @version v2.7.8 * @link http://sennajs.com * @license BSD-3-Clause */ @@ -10653,6 +10653,22 @@ var RequestScreen = function (_Screen) { return statusCode >= 200 && statusCode <= 399; } + /** + * Returns the form data + * This method can be extended in order to have a custom implementation of the form params + * @param {!Element} formElement + * @param {!Element} submittedButtonElement + * @return {!FormData} + */ + + }, { + key: 'getFormData', + value: function getFormData(formElement, submittedButtonElement) { + var formData = new FormData(formElement); + this.maybeAppendSubmitButtonValue_(formData, submittedButtonElement); + return formData; + } + /** * @inheritDoc */ @@ -10674,8 +10690,7 @@ var RequestScreen = function (_Screen) { }); if (globals.capturedFormElement) { this.addSafariXHRPolyfill(); - body = new FormData(globals.capturedFormElement); - this.maybeAppendSubmitButtonValue_(body); + body = this.getFormData(globals.capturedFormElement, globals.capturedFormButtonElement); httpMethod = RequestScreen.POST; if (UA.isIeOrEdge) { headers.add('If-None-Match', '"0"'); @@ -10713,15 +10728,15 @@ var RequestScreen = function (_Screen) { * Adds aditional data to the body of the request in case a submit button * is captured during form submission. * @param {!FormData} body The FormData containing the request body. - * @protected + * @param {!Element} submittedButtonElement + * @protected */ }, { key: 'maybeAppendSubmitButtonValue_', - value: function maybeAppendSubmitButtonValue_(body) { - var button = globals.capturedFormButtonElement; - if (button && button.name) { - body.append(button.name, button.value); + value: function maybeAppendSubmitButtonValue_(formData, submittedButtonElement) { + if (submittedButtonElement && submittedButtonElement.name) { + formData.append(submittedButtonElement.name, submittedButtonElement.value); } } @@ -11684,7 +11699,7 @@ globals.document.addEventListener('DOMContentLoaded', function () { * @returns String containing the current senna version */ -var version = '2.7.7'; +var version = '2.7.8'; exports['default'] = App$1; exports.dataAttributeHandler = dataAttributeHandler; diff --git a/build/globals/senna-min.js b/build/globals/senna-min.js index 1ea3413..a28886e 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.7 + * @version v2.7.8 * @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(e){return void 0!==e}function n(e){return t(e)&&!a(e)}function r(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&9===e.nodeType}function i(e){return"function"==typeof e}function a(e){return null===e}function o(e){var t="undefined"==typeof e?"undefined":Te(e);return"object"===t&&null!==e||"function"===t}function s(e){return"string"==typeof e||e instanceof String}function u(){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 l(e){return e=e||[],Array.isArray(e)?e:[e]}function c(e,t){if(o(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 k(e,t){return r(e)?e.documentElement.contains(t):e.contains(t)}function E(e,t,n,r,i){var a=ze[t];return a&&a.delegate&&(t=a.originalEvent,r=a.handler.bind(a,r)),i&&(r=r.bind(),r.defaultListener_=!0),y(e,t),s(n)?v(e,t,n,r):d(n,t,r),new We(s(n)?e:n,t,r,s(n)?n:null)}function b(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||O(e,"fieldset[disabled]"))}function S(e){return n(e)&&"number"==typeof e.length&&"function"==typeof e.item}function w(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function P(e){A(e);var t=!0,n=e.currentTarget,r=[];return t&=q(n,e,r),t&=M(r,e),e.delegateTarget=null,e[Ge]=n,t}function L(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):C(e,t)}function C(e,t){var n=e.parentNode;if(n)for(var r=n.querySelectorAll(t),i=0;i0&&void 0!==arguments[0]?arguments[0]:{};nt=e}function z(){return"undefined"!=typeof window&&window.__METAL_COMPATIBILITY__&&$(window.__METAL_COMPATIBILITY__),nt}function G(e,t){return e||t}function X(e){if(!e.name){var t=e.toString();e.name=t.substring(9,t.indexOf("("))}return e.name}function K(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:G,r=t+"_MERGED";if(!e.hasOwnProperty(r)){var i=e.hasOwnProperty(t)?e[t]:null;e.__proto__&&!e.__proto__.isPrototypeOf(Function)&&(i=n(i,K(e.__proto__,t,n))),e[r]=i}return e[r]}function Z(e,t){if(e){var n=e[it];return t&&!e.hasOwnProperty(it)&&(n=null),n||(e[it]=rt++)}return rt++}function ee(e){return e}function te(e){return"boolean"==typeof e}function ne(e){return void 0!==e}function re(e){return ne(e)&&!ue(e)}function ie(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&9===e.nodeType}function ae(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&11===e.nodeType}function oe(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&1===e.nodeType}function se(e){return"function"==typeof e}function ue(e){return null===e}function le(e){return"number"==typeof e}function ce(e){return null!==e&&e===e.window}function he(e){var t="undefined"==typeof e?"undefined":Te(e);return"object"===t&&null!==e||"function"===t}function fe(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&"function"==typeof e.then}function de(e){return"string"==typeof e||e instanceof String}function ve(){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 pe(){}function ye(e){var t=document.createElement("a");if(t.href=e,":"===t.protocol||!/:/.test(t.href))throw new TypeError(e+" is not a valid URL");return{hash:t.hash,hostname:t.hostname,password:t.password,pathname:"/"===t.pathname[0]?t.pathname:"/"+t.pathname,port:t.port,protocol:t.protocol,search:t.search,username:t.username}}function me(e){if(se(URL)&&URL.length){var t=new URL(e);if(t.port&&t.href.indexOf(t.port)===-1)throw new TypeError(e+" is not a valid URL");return t}return ye(e)}function _e(e){return e=e||[],Array.isArray(e)?e:[e]}function ge(e,t){return function n(){var r=arguments;ke(n),n.id=setTimeout(function(){e.apply(null,r)},t)}}function ke(e){clearTimeout(e.id)}function Ee(e){return{match:e[0],prefix:e[1],name:e[2],paramPattern:e[3],unnamedPattern:e[4],modifier:e[5]}}function be(e){for(var t="",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=l(t);for(var n=0;n>>0),at=Object.freeze({UID_PROPERTY:it,abstractMethod:J,disableCompatibilityMode:Y,enableCompatibilityMode:$,getCompatibilityModeData:z,getFunctionName:X,getStaticProperty:K,getUid:Z,identityFunction:ee,isBoolean:te,isDef:ne,isDefAndNotNull:re,isDocument:ie,isDocumentFragment:ae,isElement:oe,isFunction:se,isNull:ue,isNumber:le,isWindow:ce,isObject:he,isPromise:fe,isString:de,isServerSide:ve,nullFunction:pe}),ot=function(){function e(){Re(this,e)}return Oe(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&&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 l(e){return e=e||[],Array.isArray(e)?e:[e]}function c(e,t){if(o(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 k(e,t){return r(e)?e.documentElement.contains(t):e.contains(t)}function E(e,t,n,r,i){var a=ze[t];return a&&a.delegate&&(t=a.originalEvent,r=a.handler.bind(a,r)),i&&(r=r.bind(),r.defaultListener_=!0),y(e,t),s(n)?v(e,t,n,r):d(n,t,r),new We(s(n)?e:n,t,r,s(n)?n:null)}function b(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||O(e,"fieldset[disabled]"))}function S(e){return n(e)&&"number"==typeof e.length&&"function"==typeof e.item}function w(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function P(e){A(e);var t=!0,n=e.currentTarget,r=[];return t&=q(n,e,r),t&=M(r,e),e.delegateTarget=null,e[Ge]=n,t}function L(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):C(e,t)}function C(e,t){var n=e.parentNode;if(n)for(var r=n.querySelectorAll(t),i=0;i0&&void 0!==arguments[0]?arguments[0]:{};nt=e}function z(){return"undefined"!=typeof window&&window.__METAL_COMPATIBILITY__&&$(window.__METAL_COMPATIBILITY__),nt}function G(e,t){return e||t}function X(e){if(!e.name){var t=e.toString();e.name=t.substring(9,t.indexOf("("))}return e.name}function K(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:G,r=t+"_MERGED";if(!e.hasOwnProperty(r)){var i=e.hasOwnProperty(t)?e[t]:null;e.__proto__&&!e.__proto__.isPrototypeOf(Function)&&(i=n(i,K(e.__proto__,t,n))),e[r]=i}return e[r]}function Z(e,t){if(e){var n=e[it];return t&&!e.hasOwnProperty(it)&&(n=null),n||(e[it]=rt++)}return rt++}function ee(e){return e}function te(e){return"boolean"==typeof e}function ne(e){return void 0!==e}function re(e){return ne(e)&&!ue(e)}function ie(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&9===e.nodeType}function ae(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&11===e.nodeType}function oe(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&1===e.nodeType}function se(e){return"function"==typeof e}function ue(e){return null===e}function le(e){return"number"==typeof e}function ce(e){return null!==e&&e===e.window}function he(e){var t="undefined"==typeof e?"undefined":Te(e);return"object"===t&&null!==e||"function"===t}function fe(e){return e&&"object"===("undefined"==typeof e?"undefined":Te(e))&&"function"==typeof e.then}function de(e){return"string"==typeof e||e instanceof String}function ve(){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 pe(){}function ye(e){var t=document.createElement("a");if(t.href=e,":"===t.protocol||!/:/.test(t.href))throw new TypeError(e+" is not a valid URL");return{hash:t.hash,hostname:t.hostname,password:t.password,pathname:"/"===t.pathname[0]?t.pathname:"/"+t.pathname,port:t.port,protocol:t.protocol,search:t.search,username:t.username}}function me(e){if(se(URL)&&URL.length){var t=new URL(e);if(t.port&&t.href.indexOf(t.port)===-1)throw new TypeError(e+" is not a valid URL");return t}return ye(e)}function _e(e){return e=e||[],Array.isArray(e)?e:[e]}function ge(e,t){return function n(){var r=arguments;ke(n),n.id=setTimeout(function(){e.apply(null,r)},t)}}function ke(e){clearTimeout(e.id)}function Ee(e){return{match:e[0],prefix:e[1],name:e[2],paramPattern:e[3],unnamedPattern:e[4],modifier:e[5]}}function be(e){for(var t="",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=l(t);for(var n=0;n>>0),at=Object.freeze({UID_PROPERTY:it,abstractMethod:J,disableCompatibilityMode:Y,enableCompatibilityMode:$,getCompatibilityModeData:z,getFunctionName:X,getStaticProperty:K,getUid:Z,identityFunction:ee,isBoolean:te,isDef:ne,isDefAndNotNull:re,isDocument:ie,isDocumentFragment:ae,isElement:oe,isFunction:se,isNull:ue,isNumber:le,isWindow:ce,isObject:he,isPromise:fe,isString:de,isServerSide:ve,nullFunction:pe}),ot=function(){function e(){Re(this,e)}return Oe(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&&void 0!==arguments[0]?arguments[0]:"";Re(this,e),this.url=e.parse(this.maybeAddProtocolAndHostname_(t))}return Oe(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_(),ne(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 ft;var n=this.url.search;n&&n.substring(1).split("&").forEach(function(n){var r=n.split("="),i=He(r,2),a=i[0],o=i[1];ne(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,ne(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,ct.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 pt}},{key:"parse",value:function(e){return pt(e)}},{key:"setParseFn",value:function(e){pt=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(tt.document,"referrer",{configurable:!0,get:function(){return e}})}}]),e}(),gt={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"},kt=function(e){function t(e,n,r){Re(this,t);var i=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return i.emitter_=e,i.event_=n,i.listener_=r,i}return Ie(t,e),Oe(t,[{key:"disposeInternal",value:function(){this.removeListener(),this.emitter_=null,this.listener_=null}},{key:"removeListener",value:function(){this.emitter_.isDisposed()||this.emitter_.removeListener(this.event_,this.listener_)}}]),t}(ut),Et=[0],bt=function(e){function t(){Re(this,t);var e=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.events_=null,e.listenerHandlers_=null,e.shouldUseFacade_=!1,e}return Ie(t,e),Oe(t,[{key:"addHandler_",value:function(e,t){return e?(Array.isArray(e)||(e=[e]),e.push(t)):e=t,e}},{key:"addListener",value:function(e,t,n){this.validateListener_(t);for(var r=this.toEventsArray_(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=_e(t);for(var n=0;n0?this.unhandledRejectionId_=0:0===Vt.UNHANDLED_REJECTION_DELAY&&(this.hadUnhandledRejection_=!1);try{var n=this;e.call(t,function(e){n.resolve_(Vt.State_.FULFILLED,e)},function(e){n.resolve_(Vt.State_.REJECTED,e)})}catch(r){this.resolve_(Vt.State_.REJECTED,r)}};Lt.UNHANDLED_REJECTION_DELAY=0,Lt.State_={PENDING:0,BLOCKED:1,FULFILLED:2,REJECTED:3},Lt.CallbackEntry_=null,Lt.resolve=function(e){return new Lt(function(t){t(e)})},Lt.reject=function(e){return new Lt(function(t,n){n(e)})},Lt.race=function(e){return new Lt(function(t,n){e.length||t(void 0);for(var r,i=0;r=e[i];i++)r.then(t,n)})},Lt.all=function(e){return new Lt(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)},s=function(e){n(e)},u=0;a=e[u];u++)a.then(Pt(o,u),s)})},Lt.firstFulfilled=function(e){return new Lt(function(t,n){var r=e.length,i=[];if(!r)return void t(void 0);for(var a,o=function(e){t(e)},s=function(e,t){r--,i[e]=t,0===r&&n(i)},u=0;a=e[u];u++)a.then(o,Pt(s,u))})},Lt.prototype.then=function(e,t,n){return this.addChildPromise_(se(e)?e:null,se(t)?t:null,n)},wt.addImplementation(Lt),Lt.prototype.thenAlways=function(e,t){var n=function(){try{e.call(t)}catch(n){Lt.handleRejection_.call(null,n)}};return this.addCallbackEntry_({child:null,onRejected:n,onFulfilled:n}),this},Lt.prototype.thenCatch=function(e,t){return this.addChildPromise_(null,e,t)},Lt.prototype["catch"]=Lt.prototype.thenCatch,Lt.prototype.cancel=function(e){this.state_===Lt.State_.PENDING&&st.run(function(){var t=new Lt.CancellationError(e);t.IS_CANCELLATION_ERROR=!0,this.cancelInternal_(t)},this)},Lt.prototype.cancelInternal_=function(e){this.state_===Lt.State_.PENDING&&(this.parent_?this.parent_.cancelChild_(this,e):this.resolve_(Lt.State_.REJECTED,e))},Lt.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_===Lt.State_.PENDING&&1===r)this.cancelInternal_(t);else{var s=this.callbackEntries_.splice(i,1)[0];this.executeCallback_(s,Lt.State_.REJECTED,t)}}},Lt.prototype.addCallbackEntry_=function(e){this.callbackEntries_&&this.callbackEntries_.length||this.state_!==Lt.State_.FULFILLED&&this.state_!==Lt.State_.REJECTED||this.scheduleCallbacks_(),this.callbackEntries_||(this.callbackEntries_=[]),this.callbackEntries_.push(e)},Lt.prototype.addChildPromise_=function(e,t,n){var r={child:null,onFulfilled:null,onRejected:null};return r.child=new Lt(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);!ne(r)&&e.IS_CANCELLATION_ERROR?a(e):i(r)}catch(o){a(o)}}:a}),r.child.parent_=this,this.addCallbackEntry_(r),r.child},Lt.prototype.unblockAndFulfill_=function(e){if(this.state_!==Lt.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=Lt.State_.PENDING,this.resolve_(Lt.State_.FULFILLED,e)},Lt.prototype.unblockAndReject_=function(e){if(this.state_!==Lt.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=Lt.State_.PENDING,this.resolve_(Lt.State_.REJECTED,e)},Lt.prototype.resolve_=function(e,t){if(this.state_===Lt.State_.PENDING){if(this===t)e=Lt.State_.REJECTED,t=new TypeError("CancellablePromise cannot resolve to itself");else{if(wt.isImplementedBy(t))return t=t,this.state_=Lt.State_.BLOCKED,void t.then(this.unblockAndFulfill_,this.unblockAndReject_,this);if(he(t))try{var n=t.then;if(se(n))return void this.tryThen_(t,n)}catch(r){e=Lt.State_.REJECTED,t=r}}this.result_=t,this.state_=e,this.scheduleCallbacks_(),e!==Lt.State_.REJECTED||t.IS_CANCELLATION_ERROR||Lt.addUnhandledRejection_(this,t)}},Lt.prototype.tryThen_=function(e,t){this.state_=Lt.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)}},Lt.prototype.scheduleCallbacks_=function(){this.executing_||(this.executing_=!0,st.run(this.executeCallbacks_,this))},Lt.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===Lt.UNHANDLED_REJECTION_DELAY)for(e=this;e&&e.hadUnhandledRejection_;e=e.parent_)e.hadUnhandledRejection_=!1},Lt.addUnhandledRejection_=function(e,t){Lt.UNHANDLED_REJECTION_DELAY>0?e.unhandledRejectionId_=setTimeout(function(){Lt.handleRejection_.call(null,t)},Lt.UNHANDLED_REJECTION_DELAY):0===Lt.UNHANDLED_REJECTION_DELAY&&(e.hadUnhandledRejection_=!0,st.run(function(){e.hadUnhandledRejection_&&Lt.handleRejection_.call(null,t)}))},Lt.handleRejection_=st.throwException,Lt.setUnhandledRejectionHandler=function(e){Lt.handleRejection_=e},Lt.CancellationError=function(e){function t(e){Re(this,t);var n=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return e&&(n.message=e),n}return Ie(t,e),t}(Error),Lt.CancellationError.prototype.name="cancel";var Ct=/([\/])?(?:(?:\:(\w+)(?:\(((?:\\.|[^\\()])*)\))?|\(((?:\\.|[^\\()])+)\))([+*?])?)/g,At=function(){function e(t,n){if(Re(this,e),!re(t))throw new Error("Route path not specified.");if(!se(n))throw new Error("Route handler is not a function.");this.handler=n,this.path=t}return Oe(e,[{key:"buildParsedData_",value:function(){if(!this.parsedData_){var e=Le(this.path),t=Ce(e);this.parsedData_={regex:t,tokens:e}}return this.parsedData_}},{key:"extractParams",value:function(e){return de(this.path)?Ae(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 se(t)?t(e):(de(t)&&(t=this.buildParsedData_().regex),t instanceof RegExp&&e.search(t)>-1)}}]),e}(),Tt=function(e){function t(){Re(this,t);var e=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.cache=null,e.cacheable=!1,e}return Ie(t,e),Oe(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}(ut),Rt=function(e){function t(){Re(this,t);var e=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.id=e.makeId_(Z()),e.metas=null,e.title=null,e}return Ie(t,e),Oe(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(){Ne(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&&Ze.runScriptsInElement(e[t].activeChild)}),Lt.resolve()}},{key:"evaluateStyles",value:function(){return Lt.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)}),Lt.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 Lt.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}(Tt);Rt.isImplementedBy=function(e){return e instanceof Rt};var Ot=function(e){function t(e){Re(this,t);var n=De(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 Ie(t,e),Oe(t,[{key:"addContent",value:function(e,t){var n=this.defaultChild;re(t)&&(n=this.getChild(e),n?I(n):(n=this.createChild(e),this.transition(n,null)),_(n,t));var r=this.getElement();return r&&n&&_(r,n),n}},{key:"createChild",value:function(e){var t=tt.document.createElement("div");return t.setAttribute("id",this.makeId_(e)),t}},{key:"getChild",value:function(e){return tt.document.getElementById(this.makeId_(e))}},{key:"getElement",value:function(){return this.element?this.element:(this.element=tt.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=tt.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&&w(t)})}},{key:"remove",value:function(e){var t=this.getChild(e);t&&w(t)}},{key:"toString",value:function(){return this.id}},{key:"transition",value:function(e,n){var r=this.transitionFn||t.defaultTransition;return Lt.resolve(r.call(this,e,n))}}]),t}(ut);Ot.DEFAULT="default",Ot.defaultTransition=function(e,t){e&&(e.style.display="none",e.classList.remove("flipped")),t&&(t.style.display="block",t.classList.add("flipped"))};var Nt={IMMEDIATE:"immediate",SCHEDULE_LAST:"scheduleLast"},It=function(e){function t(){Re(this,t);var e=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.activeScreen=null,e.activePath=null,e.allowPreventNavigate=!0,e.basePath="",e.browserPathBeforeNavigate=_t.getCurrentBrowserPathWithoutHash(),e.captureScrollPositionFromScrollEvent=!0,e.defaultTitle=tt.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 tt.window.history,e.navigationStrategy=Nt.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 St,e.appEventHandlers_.add(T(tt.window,"scroll",ge(e.onScroll_.bind(e),100)),T(tt.window,"load",e.onLoad_.bind(e)),T(tt.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 Ie(t,e),Oe(t,[{key:"addRoutes",value:function(e){var t=this;return Array.isArray(e)||(e=[e]),e.forEach(function(e){e instanceof At||(e=new At(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){de(e)&&(e=new Ot(e)),t.surfaces[e.getId()]=e}),this}},{key:"canNavigate",value:function(e){var t=_t.isWebUri(e);if(!t)return!1;var n=_t.getUrlPath(e);return!!this.isLinkSameOrigin_(t.getHost())&&(!!this.isSameBasePath_(n)&&((!t.getHash()||!_t.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===Rt||Rt.isImplementedBy(r.prototype)?new r:r(t)||new Rt}return n}},{key:"disposeInternal",value:function(){this.activeScreen&&this.removeScreen(this.activePath),this.clearScreensCache(),this.formEventHandler_.removeListener(),this.linkEventHandler_.removeListener(),this.appEventHandlers_.removeAllListeners(),Ne(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"disposeInternal",this).call(this)}},{key:"dispatch",value:function(){return this.navigate(_t.getCurrentBrowserPath(),!0)}},{key:"doNavigate_",value:function(e,t){var n=this,r=this.findRoute(e);if(!r)return this.pendingNavigate=Lt.reject(new Lt.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=Nt.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=Nt.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=_t.getCurrentBrowserPathWithoutHash(),this.screens[e]=t,this.isNavigationPending=!1,this.pendingNavigate=null,tt.capturedFormElement=null,tt.capturedFormButtonElement=null}},{key:"findRoute",value:function(e){e=this.getRoutePath(e);for(var t=0;t0}},{key:"isLinkSameOrigin_",value:function(e){var t=new yt(e),n=new yt(tt.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=tt.window.history.state;if(e){var t=!1,n=function r(){tt.document.removeEventListener("scroll",r,!1),t||(tt.window.scrollTo(e.scrollLeft,e.scrollTop),t=!0)};st.nextTick(n),tt.document.addEventListener("scroll",n,!1)}}},{key:"maybeDisableNativeScrollRestoration",value:function(){this.nativeScrollRestorationSupported&&(this.nativeScrollRestoration_=tt.window.history.scrollRestoration,tt.window.history.scrollRestoration="manual")}},{key:"maybeScheduleNavigation_",value:function(e,t){return!(!this.isNavigationPending||this.navigationStrategy!==Nt.SCHEDULE_LAST)&&(this.scheduledNavigationQueue=[lt.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(_t.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 Lt.resolve().then(function(){return e.beforeActivate()}).then(function(e){if(e)return t.pendingNavigate=Lt.reject(new Lt.CancellationError("Cancelled by next screen")),t.pendingNavigate})}},{key:"maybePreventDeactivate_",value:function(){var e=this;return Lt.resolve().then(function(){if(e.activeScreen)return e.activeScreen.beforeDeactivate()}).then(function(t){if(t)return e.pendingNavigate=Lt.reject(new Lt.CancellationError("Cancelled by active screen")),e.pendingNavigate})}},{key:"maybeRepositionScrollToHashedAnchor",value:function(){var e=tt.window.location.hash;if(e){var t=tt.document.getElementById(e.substring(1));if(t){var n=_t.getNodeOffset(t),r=n.offsetLeft,i=n.offsetTop;tt.window.scrollTo(r,i)}}}},{key:"maybeRestoreNativeScrollRestoration",value:function(){this.nativeScrollRestorationSupported&&this.nativeScrollRestoration_&&(tt.window.history.scrollRestoration=this.nativeScrollRestoration_)}},{key:"maybeRestoreRedirectPathHash_",value:function(e,t,n){return t===_t.getUrlPathWithoutHash(e)?t+n:t}},{key:"maybeUpdateScrollPositionState_",value:function(){var e=tt.window.location.hash,t=tt.document.getElementById(e.substring(1));if(t){var n=_t.getNodeOffset(t),r=n.offsetLeft,i=n.offsetTop;this.saveHistoryCurrentPageScrollPosition_(i,r)}}},{key:"navigate",value:function(e,t,n){if(!_t.isHtml5HistorySupported())throw new Error("HTML5 History is not supported. Senna will not intercept navigation.");return n&&(tt.capturedFormElement=n.capturedFormElement,tt.capturedFormButtonElement=n.capturedFormButtonElement),e===this.activePath&&(t=!0),this.emit("beforeNavigate",{event:n,path:e,replaceHistory:!!t}),this.pendingNavigate}},{key:"onBeforeNavigate_",value:function(e){tt.capturedFormElement&&(e.form=tt.capturedFormElement)}},{key:"onBeforeNavigateDefault_",value:function(e){(!this.pendingNavigate||this.pendingNavigate.path!==e.path&&this.navigationStrategy!==Nt.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]";L(tt.document.activeElement,n)?e.capturedFormButtonElement=tt.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(_t.isCurrentBrowserPath(this.browserPathBeforeNavigate))return void this.maybeRepositionScrollToHashedAnchor();var t=e.state;if(!t)return void(tt.window.location.hash?(this.redirectPath&&!_t.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&&_t.setReferrer(t.referrer)});var n=new yt(t.path);n.setHostname(tt.window.location.hostname),n.setPort(tt.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_(tt.window.pageYOffset,tt.window.pageXOffset)}},{key:"onStartNavigate_",value:function(e){var t=this;this.maybeDisableNativeScrollRestoration(),this.captureScrollPositionFromScrollEvent=!1,c(tt.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||(D(tt.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 Lt.reject(new Lt.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();de(r)||(r=this.getDefaultTitle());var i=t.beforeUpdateHistoryPath(e),a={form:re(tt.capturedFormElement),path:e,redirectPath:i,scrollLeft:0,scrollTop:0,senna:!0};n&&(a.scrollTop=this.popstateScrollTop,a.scrollLeft=this.popstateScrollLeft);var o=new yt(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(){tt.window.location.reload()}},{key:"removeRoute",value:function(e){return ot.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=tt.window.history.state;if(n&&n.senna){var r=[e,t];n.scrollTop=r[0],n.scrollLeft=r[1],tt.window.history.replaceState(n,null,null)}}},{key:"setAllowPreventNavigate",value:function(e){this.allowPreventNavigate=e}},{key:"setBasePath",value:function(e){this.basePath=_t.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_=E(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_=E(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=tt.window.history.state;if(t){var n=t.scrollTop,r=t.scrollLeft,i=function(){e.updateScrollPosition&&tt.window.scrollTo(r,n)};return new Lt(function(e){return i()&st.nextTick(function(){return i()&e()})})}}},{key:"updateHistory_",value:function(e,t,n,r){var i=tt.window.location.href;n&&(n.referrer=i),r?tt.window.history.replaceState(n,e,t):tt.window.history.pushState(n,e,t),_t.setReferrer(i);var a=tt.document.querySelector("title");a?a.innerHTML=e:tt.document.title=e}}]),t}(bt),Dt=function(){function e(){Re(this,e)}return Oe(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,s,u){e=e||"",n=n||"GET";var t=new XMLHttpRequest,l=0,c=new Lt(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(h)});if(e=new yt(e),a&&e.addParametersFromMultiMap(a).toString(),e=e.toString(),t.open(n,e,!s),u&&(t.withCredentials=!0),i&&i.names().forEach(function(e){t.setRequestHeader(e,i.getAll(e).join(", "))}),t.send(ne(r)?r:null),re(o))var h=setTimeout(function(){c.cancel("Request timeout")},o);return c}}]),e}(),Ht=function Wt(){Re(this,Wt)};Ht.INVALID_STATUS="Invalid status code",Ht.REQUEST_ERROR="Request error",Ht.REQUEST_TIMEOUT="Request timeout",Ht.REQUEST_PREMATURE_TERMINATION="Request terminated prematurely";var xt=function(){function e(){Re(this,e)}return Oe(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(xt,"globals",{writable:!0,value:{window:ve()?null:window}}),xt.testUserAgent(xt.getNativeUserAgent(),xt.getNativePlatform());var Ut=function(e){function t(){Re(this,t);var e=De(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 Ie(t,e),Oe(t,[{key:"assertValidResponseStatusCode",value:function(e){if(!this.isValidResponseStatusCode(e)){var t=new Error(Ht.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 yt(e);return n.setHostname(tt.window.location.hostname),n.setProtocol(tt.window.location.protocol),tt.window.location.port&&n.setPort(tt.window.location.port),xt.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),xt.isIeOrEdge&&this.httpMethod===t.GET&&(n=new yt(n).removeUnique().toString()),_t.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(re(r))return Lt.resolve(r);var i=null,a=this.httpMethod,o=new ft;Object.keys(this.httpHeaders).forEach(function(e){return o.add(e,n.httpHeaders[e])}),tt.capturedFormElement&&(this.addSafariXHRPolyfill(),i=new FormData(tt.capturedFormElement),this.maybeAppendSubmitButtonValue_(i),a=t.POST,xt.isIeOrEdge&&o.add("If-None-Match",'"0"'));var s=this.formatLoadPath(e);return Dt.request(s,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=s,e.responseText})["catch"](function(e){switch(n.removeSafariXHRPolyfill(),e.message){case Ht.REQUEST_TIMEOUT:e.timeout=!0;break;case Ht.REQUEST_ERROR:e.requestError=!0;break;case Ht.REQUEST_PREMATURE_TERMINATION:e.requestError=!0,e.requestPrematureTermination=!0}throw e})}},{key:"maybeAppendSubmitButtonValue_",value:function(e){var t=tt.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(tt.capturedFormElement&&xt.isSafari)for(var e=tt.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(tt.capturedFormElement&&xt.isSafari)for(var e=tt.capturedFormElement.querySelectorAll('input[type="file"][data-safari-temp-disabled]'),t=0;t/gi,"/senna>");var n=void 0;if(xt.isIe){var r=tt.document.createRange().createContextualFragment(e);n=r.querySelector("senna")}else t.innerHTML=e,n=t.querySelector("senna");n&&(_t.clearNodeAttributes(t),_t.copyNodeAttributes(n,t))}},{key:"disposeInternal",value:function(){this.disposePendingStyles(),Ne(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"disposeInternal",this).call(this)}},{key:"disposePendingStyles",value:function(){this.pendingStyles&&_t.removeElementsFromDocument(this.pendingStyles)}},{key:"evaluateScripts",value:function(e){var n=this,r=this.evaluateTrackedResources_(Ze.runScriptsInElement,t.selectors.scripts,t.selectors.scriptsTemporary,t.selectors.scriptsPermanent);return r.then(function(){return Ne(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_(et.runStylesInElement,t.selectors.styles,t.selectors.stylesTemporary,t.selectors.stylesPermanent,this.appendStyleIntoDocument_.bind(this));return r.then(function(){return Ne(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 Lt(function(t){_t.removeElementsFromDocument(r),e.runFaviconInElement_(n).then(function(){return t()})})}},{key:"evaluateTrackedResources_",value:function(e,n,r,i,a){var o=this,s=this.virtualQuerySelectorAll_(n),u=this.querySelectorAll_(r),l=this.querySelectorAll_(i);l.forEach(function(e){var n=o.getResourceKey_(e);n&&(t.permanentResourcesInDoc[n]=!0)});var c=g();return s.forEach(function(e){var n=o.getResourceKey_(e);t.permanentResourcesInDoc[n]||c.appendChild(e),n&&L(e,i)&&(t.permanentResourcesInDoc[n]=!0)}),new Lt(function(t){e(c,function(){_t.removeElementsFromDocument(u),t()},a)})}},{key:"flip",value:function(e){var n=this;return Ne(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"flip",this).call(this,e).then(function(){_t.clearNodeAttributes(tt.document.documentElement),_t.copyNodeAttributes(n.virtualDocument,tt.document.documentElement),n.evaluateFavicon_(),n.updateMetaTags_()})}},{key:"updateMetaTags_",value:function(){var e=this.querySelectorAll_("meta"),t=this.metas;e&&(_t.removeElementsFromDocument(e),t&&t.forEach(function(e){return tt.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+"-"+Ot.DEFAULT);return n?n.innerHTML:t.innerHTML}}},{key:"getTitleSelector",value:function(){return this.titleSelector}},{key:"load",value:function(e){var n=this;return Ne(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(),xt.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=tt.document.createElement(e.tagName);e.href=new yt(e.href).makeUnique().toString(),_t.copyNodeAttributes(e,t),e.parentNode.replaceChild(t,e),e.disabled=!0}}},{key:"runFaviconInElement_",value:function(e){return new Lt(function(t){e.forEach(function(e){return document.head.appendChild(xt.isIe?e:_t.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(tt.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}(Ut),Ft=':not([rel="Shortcut Icon"]):not([rel="shortcut icon"]):not([rel="icon"]):not([href$="favicon.icon"])';jt.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]"+Ft,stylesPermanent:'style[data-senna-track="permanent"],link[data-senna-track="permanent"]'+Ft,stylesTemporary:'style[data-senna-track="temporary"],link[data-senna-track="temporary"]'+Ft},jt.permanentResourcesInDoc={};var Mt=function(e){function t(){Re(this,t);var e=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.app=null,e.baseElement=null,e}return Ie(t,e),Oe(t,[{key:"handle",value:function(){if(!oe(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(gt.senna)){if(this.app)throw new Error("Senna app was already initialized.");this.app=new It,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 At(/.*/,jt))}},{key:"maybeAddSurfaces_",value:function(){var e=this,t="["+gt.surface+"]";this.querySelectorAllAsArray_(t).forEach(function(t){e.updateElementIdIfSpecialSurface_(t),e.app.addSurfaces(t.id)})}},{key:"maybeDispatch_",value:function(){this.baseElement.hasAttribute(gt.dispatch)&&this.app.dispatch()}},{key:"maybeParseLinkRoute_",value:function(e){var t=new At(this.maybeParseLinkRoutePath_(e),this.maybeParseLinkRouteHandler_(e));this.app.addRoutes(t)}},{key:"maybeParseLinkRouteHandler_",value:function(e){var t=e.getAttribute("type");return re(t)&&(t=lt.getObjectByName(t)),t}},{key:"maybeParseLinkRoutePath_",value:function(e){var t=e.getAttribute("href");return re(t)&&0===t.indexOf("regex:")&&(t=new RegExp(t.substring(6))),t}},{key:"maybeSetBasePath_",value:function(){var e=this.baseElement.getAttribute(gt.basePath);re(e)&&this.app.setBasePath(e)}},{key:"maybeSetLinkSelector_",value:function(){var e=this.baseElement.getAttribute(gt.linkSelector);re(e)&&this.app.setLinkSelector(e)}},{key:"maybeSetLoadingCssClass_",value:function(){var e=this.baseElement.getAttribute(gt.loadingCssClass);re(e)&&this.app.setLoadingCssClass(e)}},{key:"maybeSetUpdateScrollPosition_",value:function(){var e=this.baseElement.getAttribute(gt.updateScrollPosition);re(e)&&("false"===e?this.app.setUpdateScrollPosition(!1):this.app.setUpdateScrollPosition(!0))}},{key:"querySelectorAllAsArray_",value:function(e){return Array.prototype.slice.call(tt.document.querySelectorAll(e))}},{key:"updateElementIdIfSpecialSurface_",value:function(e){e.id||e!==tt.document.body||(e.id="senna_surface_"+Z())}},{key:"setBaseElement",value:function(e){this.baseElement=e}}]),t}(ut),qt=new Mt;tt.document.addEventListener("DOMContentLoaded",function(){qt.setBaseElement(tt.document.body),qt.handle()});var Bt="2.7.7";e["default"]=It,e.dataAttributeHandler=qt,e.utils=_t,e.App=It,e.HtmlScreen=jt,e.Route=At,e.RequestScreen=Ut,e.Screen=Rt,e.version=Bt,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file +return 0===e.indexOf(this.basePath)}},{key:"lockHistoryScrollPosition_",value:function(){var e=tt.window.history.state;if(e){var t=!1,n=function r(){tt.document.removeEventListener("scroll",r,!1),t||(tt.window.scrollTo(e.scrollLeft,e.scrollTop),t=!0)};st.nextTick(n),tt.document.addEventListener("scroll",n,!1)}}},{key:"maybeDisableNativeScrollRestoration",value:function(){this.nativeScrollRestorationSupported&&(this.nativeScrollRestoration_=tt.window.history.scrollRestoration,tt.window.history.scrollRestoration="manual")}},{key:"maybeScheduleNavigation_",value:function(e,t){return!(!this.isNavigationPending||this.navigationStrategy!==Nt.SCHEDULE_LAST)&&(this.scheduledNavigationQueue=[lt.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(_t.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 Lt.resolve().then(function(){return e.beforeActivate()}).then(function(e){if(e)return t.pendingNavigate=Lt.reject(new Lt.CancellationError("Cancelled by next screen")),t.pendingNavigate})}},{key:"maybePreventDeactivate_",value:function(){var e=this;return Lt.resolve().then(function(){if(e.activeScreen)return e.activeScreen.beforeDeactivate()}).then(function(t){if(t)return e.pendingNavigate=Lt.reject(new Lt.CancellationError("Cancelled by active screen")),e.pendingNavigate})}},{key:"maybeRepositionScrollToHashedAnchor",value:function(){var e=tt.window.location.hash;if(e){var t=tt.document.getElementById(e.substring(1));if(t){var n=_t.getNodeOffset(t),r=n.offsetLeft,i=n.offsetTop;tt.window.scrollTo(r,i)}}}},{key:"maybeRestoreNativeScrollRestoration",value:function(){this.nativeScrollRestorationSupported&&this.nativeScrollRestoration_&&(tt.window.history.scrollRestoration=this.nativeScrollRestoration_)}},{key:"maybeRestoreRedirectPathHash_",value:function(e,t,n){return t===_t.getUrlPathWithoutHash(e)?t+n:t}},{key:"maybeUpdateScrollPositionState_",value:function(){var e=tt.window.location.hash,t=tt.document.getElementById(e.substring(1));if(t){var n=_t.getNodeOffset(t),r=n.offsetLeft,i=n.offsetTop;this.saveHistoryCurrentPageScrollPosition_(i,r)}}},{key:"navigate",value:function(e,t,n){if(!_t.isHtml5HistorySupported())throw new Error("HTML5 History is not supported. Senna will not intercept navigation.");return n&&(tt.capturedFormElement=n.capturedFormElement,tt.capturedFormButtonElement=n.capturedFormButtonElement),e===this.activePath&&(t=!0),this.emit("beforeNavigate",{event:n,path:e,replaceHistory:!!t}),this.pendingNavigate}},{key:"onBeforeNavigate_",value:function(e){tt.capturedFormElement&&(e.form=tt.capturedFormElement)}},{key:"onBeforeNavigateDefault_",value:function(e){(!this.pendingNavigate||this.pendingNavigate.path!==e.path&&this.navigationStrategy!==Nt.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]";L(tt.document.activeElement,n)?e.capturedFormButtonElement=tt.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(_t.isCurrentBrowserPath(this.browserPathBeforeNavigate))return void this.maybeRepositionScrollToHashedAnchor();var t=e.state;if(!t)return void(tt.window.location.hash?(this.redirectPath&&!_t.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&&_t.setReferrer(t.referrer)});var n=new yt(t.path);n.setHostname(tt.window.location.hostname),n.setPort(tt.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_(tt.window.pageYOffset,tt.window.pageXOffset)}},{key:"onStartNavigate_",value:function(e){var t=this;this.maybeDisableNativeScrollRestoration(),this.captureScrollPositionFromScrollEvent=!1,c(tt.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||(D(tt.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 Lt.reject(new Lt.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();de(r)||(r=this.getDefaultTitle());var i=t.beforeUpdateHistoryPath(e),a={form:re(tt.capturedFormElement),path:e,redirectPath:i,scrollLeft:0,scrollTop:0,senna:!0};n&&(a.scrollTop=this.popstateScrollTop,a.scrollLeft=this.popstateScrollLeft);var o=new yt(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(){tt.window.location.reload()}},{key:"removeRoute",value:function(e){return ot.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=tt.window.history.state;if(n&&n.senna){var r=[e,t];n.scrollTop=r[0],n.scrollLeft=r[1],tt.window.history.replaceState(n,null,null)}}},{key:"setAllowPreventNavigate",value:function(e){this.allowPreventNavigate=e}},{key:"setBasePath",value:function(e){this.basePath=_t.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_=E(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_=E(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=tt.window.history.state;if(t){var n=t.scrollTop,r=t.scrollLeft,i=function(){e.updateScrollPosition&&tt.window.scrollTo(r,n)};return new Lt(function(e){return i()&st.nextTick(function(){return i()&e()})})}}},{key:"updateHistory_",value:function(e,t,n,r){var i=tt.window.location.href;n&&(n.referrer=i),r?tt.window.history.replaceState(n,e,t):tt.window.history.pushState(n,e,t),_t.setReferrer(i);var a=tt.document.querySelector("title");a?a.innerHTML=e:tt.document.title=e}}]),t}(bt),Dt=function(){function e(){Re(this,e)}return Oe(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,s,u){e=e||"",n=n||"GET";var t=new XMLHttpRequest,l=0,c=new Lt(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(h)});if(e=new yt(e),a&&e.addParametersFromMultiMap(a).toString(),e=e.toString(),t.open(n,e,!s),u&&(t.withCredentials=!0),i&&i.names().forEach(function(e){t.setRequestHeader(e,i.getAll(e).join(", "))}),t.send(ne(r)?r:null),re(o))var h=setTimeout(function(){c.cancel("Request timeout")},o);return c}}]),e}(),Ht=function Wt(){Re(this,Wt)};Ht.INVALID_STATUS="Invalid status code",Ht.REQUEST_ERROR="Request error",Ht.REQUEST_TIMEOUT="Request timeout",Ht.REQUEST_PREMATURE_TERMINATION="Request terminated prematurely";var xt=function(){function e(){Re(this,e)}return Oe(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(xt,"globals",{writable:!0,value:{window:ve()?null:window}}),xt.testUserAgent(xt.getNativeUserAgent(),xt.getNativePlatform());var Ut=function(e){function t(){Re(this,t);var e=De(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 Ie(t,e),Oe(t,[{key:"assertValidResponseStatusCode",value:function(e){if(!this.isValidResponseStatusCode(e)){var t=new Error(Ht.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 yt(e);return n.setHostname(tt.window.location.hostname),n.setProtocol(tt.window.location.protocol),tt.window.location.port&&n.setPort(tt.window.location.port),xt.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),xt.isIeOrEdge&&this.httpMethod===t.GET&&(n=new yt(n).removeUnique().toString()),_t.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:"getFormData",value:function(e,t){var n=new FormData(e);return this.maybeAppendSubmitButtonValue_(n,t),n}},{key:"load",value:function(e){var n=this,r=this.getCache();if(re(r))return Lt.resolve(r);var i=null,a=this.httpMethod,o=new ft;Object.keys(this.httpHeaders).forEach(function(e){return o.add(e,n.httpHeaders[e])}),tt.capturedFormElement&&(this.addSafariXHRPolyfill(),i=this.getFormData(tt.capturedFormElement,tt.capturedFormButtonElement),a=t.POST,xt.isIeOrEdge&&o.add("If-None-Match",'"0"'));var s=this.formatLoadPath(e);return Dt.request(s,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=s,e.responseText})["catch"](function(e){switch(n.removeSafariXHRPolyfill(),e.message){case Ht.REQUEST_TIMEOUT:e.timeout=!0;break;case Ht.REQUEST_ERROR:e.requestError=!0;break;case Ht.REQUEST_PREMATURE_TERMINATION:e.requestError=!0,e.requestPrematureTermination=!0}throw e})}},{key:"maybeAppendSubmitButtonValue_",value:function(e,t){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(tt.capturedFormElement&&xt.isSafari)for(var e=tt.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(tt.capturedFormElement&&xt.isSafari)for(var e=tt.capturedFormElement.querySelectorAll('input[type="file"][data-safari-temp-disabled]'),t=0;t/gi,"/senna>");var n=void 0;if(xt.isIe){var r=tt.document.createRange().createContextualFragment(e);n=r.querySelector("senna")}else t.innerHTML=e,n=t.querySelector("senna");n&&(_t.clearNodeAttributes(t),_t.copyNodeAttributes(n,t))}},{key:"disposeInternal",value:function(){this.disposePendingStyles(),Ne(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"disposeInternal",this).call(this)}},{key:"disposePendingStyles",value:function(){this.pendingStyles&&_t.removeElementsFromDocument(this.pendingStyles)}},{key:"evaluateScripts",value:function(e){var n=this,r=this.evaluateTrackedResources_(Ze.runScriptsInElement,t.selectors.scripts,t.selectors.scriptsTemporary,t.selectors.scriptsPermanent);return r.then(function(){return Ne(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_(et.runStylesInElement,t.selectors.styles,t.selectors.stylesTemporary,t.selectors.stylesPermanent,this.appendStyleIntoDocument_.bind(this));return r.then(function(){return Ne(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 Lt(function(t){_t.removeElementsFromDocument(r),e.runFaviconInElement_(n).then(function(){return t()})})}},{key:"evaluateTrackedResources_",value:function(e,n,r,i,a){var o=this,s=this.virtualQuerySelectorAll_(n),u=this.querySelectorAll_(r),l=this.querySelectorAll_(i);l.forEach(function(e){var n=o.getResourceKey_(e);n&&(t.permanentResourcesInDoc[n]=!0)});var c=g();return s.forEach(function(e){var n=o.getResourceKey_(e);t.permanentResourcesInDoc[n]||c.appendChild(e),n&&L(e,i)&&(t.permanentResourcesInDoc[n]=!0)}),new Lt(function(t){e(c,function(){_t.removeElementsFromDocument(u),t()},a)})}},{key:"flip",value:function(e){var n=this;return Ne(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"flip",this).call(this,e).then(function(){_t.clearNodeAttributes(tt.document.documentElement),_t.copyNodeAttributes(n.virtualDocument,tt.document.documentElement),n.evaluateFavicon_(),n.updateMetaTags_()})}},{key:"updateMetaTags_",value:function(){var e=this.querySelectorAll_("meta"),t=this.metas;e&&(_t.removeElementsFromDocument(e),t&&t.forEach(function(e){return tt.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+"-"+Ot.DEFAULT);return n?n.innerHTML:t.innerHTML}}},{key:"getTitleSelector",value:function(){return this.titleSelector}},{key:"load",value:function(e){var n=this;return Ne(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(),xt.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=tt.document.createElement(e.tagName);e.href=new yt(e.href).makeUnique().toString(),_t.copyNodeAttributes(e,t),e.parentNode.replaceChild(t,e),e.disabled=!0}}},{key:"runFaviconInElement_",value:function(e){return new Lt(function(t){e.forEach(function(e){return document.head.appendChild(xt.isIe?e:_t.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(tt.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}(Ut),jt=':not([rel="Shortcut Icon"]):not([rel="shortcut icon"]):not([rel="icon"]):not([href$="favicon.icon"])';Ft.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]"+jt,stylesPermanent:'style[data-senna-track="permanent"],link[data-senna-track="permanent"]'+jt,stylesTemporary:'style[data-senna-track="temporary"],link[data-senna-track="temporary"]'+jt},Ft.permanentResourcesInDoc={};var Mt=function(e){function t(){Re(this,t);var e=De(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.app=null,e.baseElement=null,e}return Ie(t,e),Oe(t,[{key:"handle",value:function(){if(!oe(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(gt.senna)){if(this.app)throw new Error("Senna app was already initialized.");this.app=new It,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 At(/.*/,Ft))}},{key:"maybeAddSurfaces_",value:function(){var e=this,t="["+gt.surface+"]";this.querySelectorAllAsArray_(t).forEach(function(t){e.updateElementIdIfSpecialSurface_(t),e.app.addSurfaces(t.id)})}},{key:"maybeDispatch_",value:function(){this.baseElement.hasAttribute(gt.dispatch)&&this.app.dispatch()}},{key:"maybeParseLinkRoute_",value:function(e){var t=new At(this.maybeParseLinkRoutePath_(e),this.maybeParseLinkRouteHandler_(e));this.app.addRoutes(t)}},{key:"maybeParseLinkRouteHandler_",value:function(e){var t=e.getAttribute("type");return re(t)&&(t=lt.getObjectByName(t)),t}},{key:"maybeParseLinkRoutePath_",value:function(e){var t=e.getAttribute("href");return re(t)&&0===t.indexOf("regex:")&&(t=new RegExp(t.substring(6))),t}},{key:"maybeSetBasePath_",value:function(){var e=this.baseElement.getAttribute(gt.basePath);re(e)&&this.app.setBasePath(e)}},{key:"maybeSetLinkSelector_",value:function(){var e=this.baseElement.getAttribute(gt.linkSelector);re(e)&&this.app.setLinkSelector(e)}},{key:"maybeSetLoadingCssClass_",value:function(){var e=this.baseElement.getAttribute(gt.loadingCssClass);re(e)&&this.app.setLoadingCssClass(e)}},{key:"maybeSetUpdateScrollPosition_",value:function(){var e=this.baseElement.getAttribute(gt.updateScrollPosition);re(e)&&("false"===e?this.app.setUpdateScrollPosition(!1):this.app.setUpdateScrollPosition(!0))}},{key:"querySelectorAllAsArray_",value:function(e){return Array.prototype.slice.call(tt.document.querySelectorAll(e))}},{key:"updateElementIdIfSpecialSurface_",value:function(e){e.id||e!==tt.document.body||(e.id="senna_surface_"+Z())}},{key:"setBaseElement",value:function(e){this.baseElement=e}}]),t}(ut),qt=new Mt;tt.document.addEventListener("DOMContentLoaded",function(){qt.setBaseElement(tt.document.body),qt.handle()});var Bt="2.7.8";e["default"]=It,e.dataAttributeHandler=qt,e.utils=_t,e.App=It,e.HtmlScreen=Ft,e.Route=At,e.RequestScreen=Ut,e.Screen=Rt,e.version=Bt,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 05315c8..7a56c98 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.7 + * @version v2.7.8 * @link http://sennajs.com * @license BSD-3-Clause */ @@ -10653,6 +10653,22 @@ var RequestScreen = function (_Screen) { return statusCode >= 200 && statusCode <= 399; } + /** + * Returns the form data + * This method can be extended in order to have a custom implementation of the form params + * @param {!Element} formElement + * @param {!Element} submittedButtonElement + * @return {!FormData} + */ + + }, { + key: 'getFormData', + value: function getFormData(formElement, submittedButtonElement) { + var formData = new FormData(formElement); + this.maybeAppendSubmitButtonValue_(formData, submittedButtonElement); + return formData; + } + /** * @inheritDoc */ @@ -10674,8 +10690,7 @@ var RequestScreen = function (_Screen) { }); if (globals.capturedFormElement) { this.addSafariXHRPolyfill(); - body = new FormData(globals.capturedFormElement); - this.maybeAppendSubmitButtonValue_(body); + body = this.getFormData(globals.capturedFormElement, globals.capturedFormButtonElement); httpMethod = RequestScreen.POST; if (UA.isIeOrEdge) { headers.add('If-None-Match', '"0"'); @@ -10713,15 +10728,15 @@ var RequestScreen = function (_Screen) { * Adds aditional data to the body of the request in case a submit button * is captured during form submission. * @param {!FormData} body The FormData containing the request body. - * @protected + * @param {!Element} submittedButtonElement + * @protected */ }, { key: 'maybeAppendSubmitButtonValue_', - value: function maybeAppendSubmitButtonValue_(body) { - var button = globals.capturedFormButtonElement; - if (button && button.name) { - body.append(button.name, button.value); + value: function maybeAppendSubmitButtonValue_(formData, submittedButtonElement) { + if (submittedButtonElement && submittedButtonElement.name) { + formData.append(submittedButtonElement.name, submittedButtonElement.value); } } @@ -11684,7 +11699,7 @@ globals.document.addEventListener('DOMContentLoaded', function () { * @returns String containing the current senna version */ -var version = '2.7.7'; +var version = '2.7.8'; exports['default'] = App$1; exports.dataAttributeHandler = dataAttributeHandler; diff --git a/build/globals/senna.js.map b/build/globals/senna.js.map index d2d77b6..27a6372 100644 --- a/build/globals/senna.js.map +++ b/build/globals/senna.js.map @@ -1 +1 @@ -{"version":3,"file":"senna.js","sources":["node_modules/metal-dom/node_modules/metal/src/coreNamed.js","node_modules/metal-dom/node_modules/metal/src/core.js","node_modules/metal-dom/node_modules/metal/src/array/array.js","node_modules/metal-dom/node_modules/metal/src/async/async.js","node_modules/metal-dom/node_modules/metal/src/disposable/Disposable.js","node_modules/metal-dom/node_modules/metal/src/object/object.js","node_modules/metal-dom/node_modules/metal/src/string/string.js","node_modules/metal-dom/src/domData.js","node_modules/metal-dom/node_modules/metal-events/src/EventHandle.js","node_modules/metal-dom/node_modules/metal-events/src/EventEmitter.js","node_modules/metal-dom/node_modules/metal-events/src/EventEmitterProxy.js","node_modules/metal-dom/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/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-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-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-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, like IE11, 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 * IE11 doesn't support Element.classList.add function, this method\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 * IE11 doesn't support Element.closest function, this method\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 * IE11 doesn't support Element.classList.add function, this method\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 * @deprecated Use element1.contains(element2) directly instead of this method\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 * IE11 doesn't support Element.matches function, this method\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 * IE11 doesn't support once event listener option, this method\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 * IE11 doesn't support Element.prepend function, this method\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 * IE11 doesn't support Element.classList, this method\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 * @deprecated Use element1.parentNode.replaceChild(element2, element1)\n * directly instead of this method\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.replaceChild(element2, 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\treturn document.querySelector(selectorOrElement);\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 * IE11 doesn't support Element.classList, this method\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 IE11, Edge) 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 (\n\t\t\tstyle.rel &&\n\t\t\tstyle.rel !== 'stylesheet' &&\n\t\t\tstyle.rel !== 'canonical' &&\n\t\t\tstyle.rel !== 'alternate'\n\t\t) {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tstyle.tagName === 'STYLE' ||\n\t\t\tstyle.rel === 'canonical' ||\n\t\t\tstyle.rel === 'alternate'\n\t\t) {\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 * 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 */\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};","'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>}\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","/*!\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":["isDef","val","undefined","isDefAndNotNull","isNull","isDocument","nodeType","isFunction","isObject","type","isString","String","isServerSide","options","checkEnv","serverSide","process","browser","env","NODE_ENV","array","arr1","arr2","length","i","arr","output","Array","isArray","flatten","push","obj","indexOf","rv","removeAt","prototype","splice","call","start","end","sliced","async","throwException","exception","nextTick","run","callback","context","workQueueScheduled_","processWorkQueue","workQueue_","WorkItem_","workItems","workItem","fn","scope","e","cb","bind","wrapCallback_","setImmediate_","setImmediate","getSetImmediateEmulator_","Channel","MessageChannel","window","postMessage","addEventListener","iframe","document","createElement","style","display","src","title","documentElement","appendChild","win","contentWindow","doc","open","write","close","message","Math","random","origin","location","protocol","host","onmessage","data","port1","port2","channel","head","tail","next","script","onreadystatechange","parentNode","removeChild","Disposable","disposed_","disposeInternal","object","target","key","source","args","name","parts","split","reduce","part","mappedObj","keys","Object","obj1","obj2","keys1","keys2","string","str1","str2","test1","toLowerCase","test2","str","replace","x","floor","toString","abs","Date","now","hash","len","charCodeAt","value","substring","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","hasOwnProperty","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","compatibilityModeData_","uniqueIdCounter_","UID_PROPERTY","abstractMethod","Error","disableCompatibilityMode","enableCompatibilityMode","getCompatibilityModeData","__METAL_COMPATIBILITY__","getFirstTruthy_","a","b","getFunctionName","getStaticProperty","ctor","propertyName","mergeFn","mergedName","merged","__proto__","isPrototypeOf","Function","getUid","noInheritance","id","identityFunction","returnValue","isBoolean","isDocumentFragment","isElement","isNumber","isWindow","isPromise","then","nullFunction","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,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvY29yZU5hbWVkLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9jb3JlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9hcnJheS9hcnJheS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvYXN5bmMvYXN5bmMuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2Rpc3Bvc2FibGUvRGlzcG9zYWJsZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvb2JqZWN0L29iamVjdC5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvc3RyaW5nL3N0cmluZy5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9kb21EYXRhLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRIYW5kbGUuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9ub2RlX21vZHVsZXMvbWV0YWwtZXZlbnRzL3NyYy9FdmVudEVtaXR0ZXIuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9ub2RlX21vZHVsZXMvbWV0YWwtZXZlbnRzL3NyYy9FdmVudEVtaXR0ZXJQcm94eS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50SGFuZGxlci5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9Eb21EZWxlZ2F0ZWRFdmVudEhhbmRsZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9Eb21FdmVudEhhbmRsZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9kb21OYW1lZC5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9kb20uanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvRG9tRXZlbnRFbWl0dGVyUHJveHkuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZmVhdHVyZXMuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZ2xvYmFsRXZhbC5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9nbG9iYWxFdmFsU3R5bGVzLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2V2ZW50cy5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvZ2xvYmFscy9nbG9iYWxzLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvY29yZU5hbWVkLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvY29yZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2FycmF5L2FycmF5LmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvYXN5bmMvYXN5bmMuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9kaXNwb3NhYmxlL0Rpc3Bvc2FibGUuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9vYmplY3Qvb2JqZWN0LmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvc3RyaW5nL3N0cmluZy5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtdXJpL3NyYy9wYXJzZUZyb21BbmNob3IuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXVyaS9zcmMvcGFyc2UuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXN0cnVjdHMvc3JjL011bHRpTWFwLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1zdHJ1Y3RzL3NyYy9UcmVlTm9kZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtdXJpL3NyYy9VcmkuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvc3JjL3V0aWxzL3V0aWxzLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9hcHAvZGF0YUF0dHJpYnV0ZXMuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRIYW5kbGUuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRFbWl0dGVyLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50RW1pdHRlclByb3h5LmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50SGFuZGxlci5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtcHJvbWlzZS9zcmMvcHJvbWlzZS9Qcm9taXNlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kZWJvdW5jZS9zcmMvZGVib3VuY2UuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXBhdGgtcGFyc2VyL3NyYy9wYXRoUGFyc2VyLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9yb3V0ZS9Sb3V0ZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvY2FjaGVhYmxlL0NhY2hlYWJsZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvc2NyZWVuL1NjcmVlbi5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvc3VyZmFjZS9TdXJmYWNlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9hcHAvQXBwLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1hamF4L3NyYy9BamF4LmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9lcnJvcnMvZXJyb3JzLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC11c2VyYWdlbnQvc3JjL1VBLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9zY3JlZW4vUmVxdWVzdFNjcmVlbi5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvc2NyZWVuL0h0bWxTY3JlZW4uanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvc3JjL2FwcC9BcHBEYXRhQXR0cmlidXRlSGFuZGxlci5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvYXBwL2RhdGFBdHRyaWJ1dGVIYW5kbGVyLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9hcHAvdmVyc2lvbi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogQSBjb2xsZWN0aW9uIG9mIGNvcmUgdXRpbGl0eSBmdW5jdGlvbnMuXG4gKiBAY29uc3RcbiAqL1xuXG5sZXQgY29tcGF0aWJpbGl0eU1vZGVEYXRhXztcblxuLyoqXG4gKiBDb3VudGVyIGZvciB1bmlxdWUgaWQuXG4gKiBAdHlwZSB7TnVtYmVyfVxuICogQHByaXZhdGVcbiAqL1xubGV0IHVuaXF1ZUlkQ291bnRlcl8gPSAxO1xuXG4vKipcbiAqIFVuaXF1ZSBpZCBwcm9wZXJ0eSBwcmVmaXguXG4gKiBAdHlwZSB7U3RyaW5nfVxuICogQHByb3RlY3RlZFxuICovXG5leHBvcnQgY29uc3QgVUlEX1BST1BFUlRZID0gYGNvcmVfJHsoTWF0aC5yYW5kb20oKSAqIDFlOSkgPj4+IDB9YDtcblxuLyoqXG4gKiBXaGVuIGRlZmluaW5nIGEgY2xhc3MgRm9vIHdpdGggYW4gYWJzdHJhY3QgbWV0aG9kIGJhcigpLCB5b3UgY2FuIGRvOlxuICogRm9vLnByb3RvdHlwZS5iYXIgPSBhYnN0cmFjdE1ldGhvZFxuICpcbiAqIE5vdyBpZiBhIHN1YmNsYXNzIG9mIEZvbyBmYWlscyB0byBvdmVycmlkZSBiYXIoKSwgYW4gZXJyb3Igd2lsbCBiZSB0aHJvd25cbiAqIHdoZW4gYmFyKCkgaXMgaW52b2tlZC5cbiAqXG4gKiBAdHlwZSB7IUZ1bmN0aW9ufVxuICogQHRocm93cyB7RXJyb3J9IHdoZW4gaW52b2tlZCB0byBpbmRpY2F0ZSB0aGUgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWJzdHJhY3RNZXRob2QoKSB7XG5cdHRocm93IEVycm9yKCdVbmltcGxlbWVudGVkIGFic3RyYWN0IG1ldGhvZCcpO1xufVxuXG4vKipcbiAqIERpc2FibGVzIE1ldGFsLmpzJ3MgY29tcGF0aWJpbGl0eSBtb2RlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzYWJsZUNvbXBhdGliaWxpdHlNb2RlKCkge1xuXHRjb21wYXRpYmlsaXR5TW9kZURhdGFfID0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgTWV0YWwuanMncyBjb21wYXRpYmlsaXR5IG1vZGUgd2l0aCB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIGZyb20gcmNcbiAqIGFuZCAxLnggdmVyc2lvbnM6XG4gKiAgICAgLSBVc2luZyBcImtleVwiIHRvIHJlZmVyZW5jZSBjb21wb25lbnQgaW5zdGFuY2VzLiBJbiB0aGUgY3VycmVudCB2ZXJzaW9uXG4gKiAgICAgICB0aGlzIHNob3VsZCBiZSBkb25lIHZpYSBcInJlZlwiIGluc3RlYWQuIFRoaXMgYWxsb3dzIG9sZCBjb2RlIHN0aWxsXG4gKiAgICAgICB1c2luZyBcImtleVwiIHRvIGtlZXAgd29ya2luZyBsaWtlIGJlZm9yZS4gTk9URTogdGhpcyBtYXkgY2F1c2VcbiAqICAgICAgIHByb2JsZW1zLCBzaW5jZSBcImtleVwiIGlzIG1lYW50IHRvIGJlIHVzZWQgZGlmZmVyZW50bHkuIE9ubHkgdXNlIHRoaXNcbiAqICAgICAgIGlmIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHVwZ3JhZGUgdGhlIGNvZGUgdG8gdXNlIFwicmVmXCIgaW5zdGVhZC5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gZGF0YSBPcHRpb25hbCBvYmplY3Qgd2l0aCBkYXRhIHRvIHNwZWNpZnkgbW9yZVxuICogICAgIGRldGFpbHMsIHN1Y2ggYXM6XG4gKiAgICAgICAgIC0gcmVuZGVyZXJzIHtBcnJheX0gdGhlIHRlbXBsYXRlIHJlbmRlcmVycyB0aGF0IHNob3VsZCBiZSBpblxuICogICAgICAgICAgIGNvbXBhdGliaWxpdHkgbW9kZSwgZWl0aGVyIHRoZWlyIGNvbnN0cnVjdG9ycyBvciBzdHJpbmdzXG4gKiAgICAgICAgICAgcmVwcmVzZW50aW5nIHRoZW0gKGUuZy4gJ3NveScgb3IgJ2pzeCcpLiBCeSBkZWZhdWx0LCBhbGwgdGhlIG9uZXNcbiAqICAgICAgICAgICB0aGF0IGV4dGVuZCBmcm9tIEluY3JlbWVudGFsRG9tUmVuZGVyZXIuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5hYmxlQ29tcGF0aWJpbGl0eU1vZGUoZGF0YSA9IHt9KSB7XG5cdGNvbXBhdGliaWxpdHlNb2RlRGF0YV8gPSBkYXRhO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGRhdGEgdXNlZCBmb3IgY29tcGF0aWJpbGl0eSBtb2RlLCBvciBub3RoaW5nIGlmIGl0IGhhc24ndCBiZWVuXG4gKiBlbmFibGVkLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29tcGF0aWJpbGl0eU1vZGVEYXRhKCkge1xuXHQvLyBDb21wYXRpYmlsaXR5IG1vZGUgY2FuIGJlIHNldCB2aWEgdGhlIF9fTUVUQUxfQ09NUEFUSUJJTElUWV9fIGdsb2JhbCB2YXIuXG5cdGlmIChjb21wYXRpYmlsaXR5TW9kZURhdGFfID09PSB1bmRlZmluZWQpIHtcblx0XHRpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Ll9fTUVUQUxfQ09NUEFUSUJJTElUWV9fKSB7XG5cdFx0XHRlbmFibGVDb21wYXRpYmlsaXR5TW9kZSh3aW5kb3cuX19NRVRBTF9DT01QQVRJQklMSVRZX18pO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gY29tcGF0aWJpbGl0eU1vZGVEYXRhXztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBpZiBpdCdzIHRydXRoeSwgb3IgdGhlIHNlY29uZCBvdGhlcndpc2UuXG4gKiBAcGFyYW0geyp9IGFcbiAqIEBwYXJhbSB7Kn0gYlxuICogQHJldHVybiB7Kn1cbiAqIEBwcm90ZWN0ZWRcbiAqL1xuZnVuY3Rpb24gZ2V0Rmlyc3RUcnV0aHlfKGEsIGIpIHtcblx0cmV0dXJuIGEgfHwgYjtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBuYW1lIG9mIHRoZSBnaXZlbiBmdW5jdGlvbi4gSWYgdGhlIGN1cnJlbnQgYnJvd3NlciBkb2Vzbid0XG4gKiBzdXBwb3J0IHRoZSBgbmFtZWAgcHJvcGVydHksIGxpa2UgSUUxMSwgdGhpcyB3aWxsIGNhbGN1bGF0ZSBpdCBmcm9tIHRoZSBmdW5jdGlvbidzXG4gKiBjb250ZW50IHN0cmluZy5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGZuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoZm4pIHtcblx0aWYgKCFmbi5uYW1lKSB7XG5cdFx0Y29uc3Qgc3RyID0gZm4udG9TdHJpbmcoKTtcblx0XHRmbi5uYW1lID0gc3RyLnN1YnN0cmluZyg5LCBzdHIuaW5kZXhPZignKCcpKTtcblx0fVxuXHRyZXR1cm4gZm4ubmFtZTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHN0YXRpYyBwcm9wZXJ0eSBpbiB0aGUgZ2l2ZW4gY2xhc3MuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gKiBpbmhlcml0ZWQgZnJvbSBhbmNlc3RvcnMgYXMgZXhwZWN0ZWQsIHVubGVzcyBhIGN1c3RvbSBtZXJnZSBmdW5jdGlvbiBpcyBnaXZlbixcbiAqIHdoaWNoIGNhbiBjaGFuZ2UgaG93IHRoZSBzdXBlciBjbGFzc2VzJyB2YWx1ZSBmb3IgdGhhdCBwcm9wZXJ0eSB3aWxsIGJlIG1lcmdlZFxuICogdG9nZXRoZXIuXG4gKiBUaGUgZmluYWwgbWVyZ2VkIHZhbHVlIHdpbGwgYmUgc3RvcmVkIGluIGFub3RoZXIgcHJvcGVydHksIHNvIHRoYXQgaXQgd29uJ3RcbiAqIGJlIHJlY2FsY3VsYXRlZCBldmVuIGlmIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG11bHRpcGxlIHRpbWVzLlxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gY3RvciBDbGFzcyBjb25zdHJ1Y3Rvci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWUgUHJvcGVydHkgbmFtZSB0byBiZSBtZXJnZWQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosICopOio9fSBtZXJnZUZuIEZ1bmN0aW9uIHRoYXQgcmVjZWl2ZXMgdGhlIG1lcmdlZFxuICogICAgIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBzbyBmYXIgYW5kIHRoZSBuZXh0IHZhbHVlIHRvIGJlIG1lcmdlZCB0byBpdC5cbiAqICAgICBTaG91bGQgcmV0dXJuIHRoZXNlIHR3byBtZXJnZWQgdG9nZXRoZXIuIElmIG5vdCBwYXNzZWQgdGhlIGZpbmFsIHByb3BlcnR5XG4gKiAgICAgd2lsbCBiZSB0aGUgZmlyc3QgdHJ1dGh5IHZhbHVlIGFtb25nIGFuY2VzdG9ycy5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0YXRpY1Byb3BlcnR5KFxuXHRjdG9yLFxuXHRwcm9wZXJ0eU5hbWUsXG5cdG1lcmdlRm4gPSBnZXRGaXJzdFRydXRoeV9cbikge1xuXHRjb25zdCBtZXJnZWROYW1lID0gcHJvcGVydHlOYW1lICsgJ19NRVJHRUQnO1xuXHRpZiAoIWN0b3IuaGFzT3duUHJvcGVydHkobWVyZ2VkTmFtZSkpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRsZXQgbWVyZ2VkID0gY3Rvci5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpXG5cdFx0XHQ/IGN0b3JbcHJvcGVydHlOYW1lXVxuXHRcdFx0OiBudWxsO1xuXHRcdGlmIChjdG9yLl9fcHJvdG9fXyAmJiAhY3Rvci5fX3Byb3RvX18uaXNQcm90b3R5cGVPZihGdW5jdGlvbikpIHtcblx0XHRcdG1lcmdlZCA9IG1lcmdlRm4oXG5cdFx0XHRcdG1lcmdlZCxcblx0XHRcdFx0Z2V0U3RhdGljUHJvcGVydHkoY3Rvci5fX3Byb3RvX18sIHByb3BlcnR5TmFtZSwgbWVyZ2VGbilcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGN0b3JbbWVyZ2VkTmFtZV0gPSBtZXJnZWQ7XG5cdH1cblx0cmV0dXJuIGN0b3JbbWVyZ2VkTmFtZV07XG59XG5cbi8qKlxuICogR2V0cyBhbiB1bmlxdWUgaWQuIElmIGBvYmplY3RgIGFyZ3VtZW50IGlzIHBhc3NlZCwgdGhlIG9iamVjdCBpc1xuICogbXV0YXRlZCB3aXRoIGFuIHVuaXF1ZSBpZC4gQ29uc2VjdXRpdmUgY2FsbHMgd2l0aCB0aGUgc2FtZSBvYmplY3RcbiAqIHJlZmVyZW5jZSB3b24ndCBtdXRhdGUgdGhlIG9iamVjdCBhZ2FpbiwgaW5zdGVhZCB0aGUgY3VycmVudCBvYmplY3QgdWlkXG4gKiByZXR1cm5zLiBTZWUge0BsaW5rIFVJRF9QUk9QRVJUWX0uXG4gKiBAcGFyYW0ge09iamVjdD19IG9iamVjdCBPcHRpb25hbCBvYmplY3QgdG8gYmUgbXV0YXRlZCB3aXRoIHRoZSB1aWQuIElmXG4gKiAgICAgbm90IHNwZWNpZmllZCB0aGlzIG1ldGhvZCBvbmx5IHJldHVybnMgdGhlIHVpZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vSW5oZXJpdGFuY2UgT3B0aW9uYWwgZmxhZyBpbmRpY2F0aW5nIGlmIHRoaXNcbiAqICAgICBvYmplY3QncyB1aWQgcHJvcGVydHkgY2FuIGJlIGluaGVyaXRlZCBmcm9tIHBhcmVudHMgb3Igbm90LlxuICogQHRocm93cyB7RXJyb3J9IHdoZW4gaW52b2tlZCB0byBpbmRpY2F0ZSB0aGUgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuLlxuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VWlkKG9iamVjdCwgbm9Jbmhlcml0YW5jZSkge1xuXHRpZiAob2JqZWN0KSB7XG5cdFx0bGV0IGlkID0gb2JqZWN0W1VJRF9QUk9QRVJUWV07XG5cdFx0aWYgKG5vSW5oZXJpdGFuY2UgJiYgIW9iamVjdC5oYXNPd25Qcm9wZXJ0eShVSURfUFJPUEVSVFkpKSB7XG5cdFx0XHRpZCA9IG51bGw7XG5cdFx0fVxuXHRcdHJldHVybiBpZCB8fCAob2JqZWN0W1VJRF9QUk9QRVJUWV0gPSB1bmlxdWVJZENvdW50ZXJfKyspO1xuXHR9XG5cdHJldHVybiB1bmlxdWVJZENvdW50ZXJfKys7XG59XG5cbi8qKlxuICogVGhlIGlkZW50aXR5IGZ1bmN0aW9uLiBSZXR1cm5zIGl0cyBmaXJzdCBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kj19IHJldHVyblZhbHVlIFRoZSBzaW5nbGUgdmFsdWUgdGhhdCB3aWxsIGJlIHJldHVybmVkLlxuICogQHJldHVybiB7P30gVGhlIGZpcnN0IGFyZ3VtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHlGdW5jdGlvbihyZXR1cm5WYWx1ZSkge1xuXHRyZXR1cm4gcmV0dXJuVmFsdWU7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBib29sZWFuLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYm9vbGVhbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbih2YWwpIHtcblx0cmV0dXJuIHR5cGVvZiB2YWwgPT09ICdib29sZWFuJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBub3QgdW5kZWZpbmVkLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmKHZhbCkge1xuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIG5vdCB1bmRlZmluZWQgb3IgbnVsbC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEZWZBbmROb3ROdWxsKHZhbCkge1xuXHRyZXR1cm4gaXNEZWYodmFsKSAmJiAhaXNOdWxsKHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgZG9jdW1lbnQuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRG9jdW1lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSA5O1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIGRvY3VtZW50LWZyYWdtZW50LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RvY3VtZW50RnJhZ21lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSAxMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBkb20gZWxlbWVudC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbGVtZW50KHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC5ub2RlVHlwZSA9PT0gMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIGZ1bmN0aW9uLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsKSB7XG5cdHJldHVybiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBudWxsLlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bGwodmFsKSB7XG5cdHJldHVybiB2YWwgPT09IG51bGw7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBhIG51bWJlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtYmVyKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ251bWJlcic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgd2luZG93LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1dpbmRvdyh2YWwpIHtcblx0cmV0dXJuIHZhbCAhPT0gbnVsbCAmJiB2YWwgPT09IHZhbC53aW5kb3c7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gb2JqZWN0LiBUaGlzIGluY2x1ZGVzIGFycmF5c1xuICogYW5kIGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGFuIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbCkge1xuXHRjb25zdCB0eXBlID0gdHlwZW9mIHZhbDtcblx0cmV0dXJuICh0eXBlID09PSAnb2JqZWN0JyAmJiB2YWwgIT09IG51bGwpIHx8IHR5cGUgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgUHJvbWlzZS5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQcm9taXNlKHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWwudGhlbiA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgfHwgdmFsIGluc3RhbmNlb2YgU3RyaW5nO1xufVxuXG4vKipcbiAqIFNldHMgdG8gdHJ1ZSBpZiBydW5uaW5nIGluc2lkZSBOb2RlLmpzIGVudmlyb25tZW50IHdpdGggZXh0cmEgY2hlY2sgZm9yXG4gKiBgcHJvY2Vzcy5icm93c2VyYCB0byBza2lwIEthcm1hIHJ1bm5lciBlbnZpcm9ubWVudC4gS2FybWEgZW52aXJvbm1lbnQgaGFzXG4gKiBgcHJvY2Vzc2AgZGVmaW5lZCBldmVuIHRob3VnaCBpdCBydW5zIG9uIHRoZSBicm93c2VyLlxuICogQHBhcmFtIHs/T2JqZWN0fSBvcHRpb25zIENvbnRhaW5zIGBjaGVja0VudmAgcHJvcGVydHkgd2hpY2ggaWYgdHJ1ZSwgY2hlY2tzXG4gKiB0aGUgTk9ERV9FTlYgdmFyaWFibGUuIElmIE5PREVfRU5WIGVxdWFscyAndGVzdCcsIHRoZSBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2VydmVyU2lkZShvcHRpb25zID0ge2NoZWNrRW52OiB0cnVlfSkge1xuXHRsZXQgc2VydmVyU2lkZSA9IHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiAhcHJvY2Vzcy5icm93c2VyO1xuXHRpZiAoc2VydmVyU2lkZSAmJiBvcHRpb25zLmNoZWNrRW52KSB7XG5cdFx0c2VydmVyU2lkZSA9XG5cdFx0XHR0eXBlb2YgcHJvY2Vzcy5lbnYgIT09ICd1bmRlZmluZWQnICYmXG5cdFx0XHRwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnO1xuXHR9XG5cdHJldHVybiBzZXJ2ZXJTaWRlO1xufVxuXG4vKipcbiAqIE51bGwgZnVuY3Rpb24gdXNlZCBmb3IgZGVmYXVsdCB2YWx1ZXMgb2YgY2FsbGJhY2tzLCBldGMuXG4gKiBAcmV0dXJuIHt2b2lkfSBOb3RoaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVsbEZ1bmN0aW9uKCkge31cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gVGhpcyBmaWxlIGV4aXN0cyBqdXN0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgbWFraW5nIHN1cmUgdGhhdCBvbGRcbi8vIGRlZmF1bHQgaW1wb3J0cyBmb3IgdGhpcyBmaWxlIHN0aWxsIHdvcmsuIEl0J3MgYmVzdCB0byB1c2UgdGhlIG5hbWVkIGV4cG9ydHNcbi8vIGZvciBlYWNoIGZ1bmN0aW9uIGluc3RlYWQgdGhvdWdoLCBzaW5jZSB0aGF0IGFsbG93cyBidW5kbGVycyBsaWtlIFJvbGx1cCB0b1xuLy8gcmVkdWNlIHRoZSBidW5kbGUgc2l6ZSBieSByZW1vdmluZyB1bnVzZWQgY29kZS5cbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnLi9jb3JlTmFtZWQnO1xuXG5leHBvcnQgZGVmYXVsdCBjb3JlO1xuZXhwb3J0IHtjb3JlfTtcbmV4cG9ydCAqIGZyb20gJy4vY29yZU5hbWVkJztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBhcnJheSBvcGVyYXRpb25zXG4gKi9cbmNsYXNzIGFycmF5IHtcblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJyYXlzIGhhdmUgdGhlIHNhbWUgY29udGVudC5cblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjFcblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBlcXVhbChhcnIxLCBhcnIyKSB7XG5cdFx0aWYgKGFycjEgPT09IGFycjIpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRpZiAoYXJyMS5sZW5ndGggIT09IGFycjIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycjFbaV0gIT09IGFycjJbaV0pIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZ2l2ZW4gYXJyYXkgdGhhdCBpc24ndCB1bmRlZmluZWQuXG5cdCAqIEBwYXJhbSB7IUFycmF5fSBhcnJcblx0ICogQHJldHVybiB7Kn1cblx0ICovXG5cdHN0YXRpYyBmaXJzdERlZmluZWRWYWx1ZShhcnIpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycltpXSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBhcnJbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRyYW5zZm9ybXMgdGhlIGlucHV0IG5lc3RlZCBhcnJheSB0byBiZWNvbWUgZmxhdC5cblx0ICogQHBhcmFtIHtBcnJheS48KnxBcnJheS48Kj4+fSBhcnIgTmVzdGVkIGFycmF5IHRvIGZsYXR0ZW4uXG5cdCAqIEBwYXJhbSB7QXJyYXkuPCo+PX0gb3V0cHV0IE9wdGlvbmFsIG91dHB1dCBhcnJheS5cblx0ICogQHJldHVybiB7QXJyYXkuPCo+fSBGbGF0IGFycmF5LlxuXHQgKi9cblx0c3RhdGljIGZsYXR0ZW4oYXJyLCBvdXRwdXQgPSBbXSkge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoQXJyYXkuaXNBcnJheShhcnJbaV0pKSB7XG5cdFx0XHRcdGFycmF5LmZsYXR0ZW4oYXJyW2ldLCBvdXRwdXQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3V0cHV0LnB1c2goYXJyW2ldKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGEgcGFydGljdWxhciB2YWx1ZSBmcm9tIGFuIGFycmF5LlxuXHQgKiBAcGFyYW0ge0FycmF5LjxUPn0gYXJyIEFycmF5IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge1R9IG9iaiBPYmplY3QgdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqIEB0ZW1wbGF0ZSBUXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlKGFyciwgb2JqKSB7XG5cdFx0Y29uc3QgaSA9IGFyci5pbmRleE9mKG9iaik7XG5cdFx0bGV0IHJ2O1xuXHRcdGlmICgocnYgPSBpID49IDApKSB7XG5cdFx0XHRhcnJheS5yZW1vdmVBdChhcnIsIGkpO1xuXHRcdH1cblx0XHRyZXR1cm4gcnY7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBmcm9tIGFuIGFycmF5IHRoZSBlbGVtZW50IGF0IGluZGV4IGlcblx0ICogQHBhcmFtIHtBcnJheX0gYXJyIEFycmF5IG9yIGFycmF5IGxpa2Ugb2JqZWN0IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gaSBUaGUgaW5kZXggdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlQXQoYXJyLCBpKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zcGxpY2UuY2FsbChhcnIsIGksIDEpLmxlbmd0aCA9PT0gMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTbGljZXMgdGhlIGdpdmVuIGFycmF5LCBqdXN0IGxpa2UgQXJyYXkucHJvdG90eXBlLnNsaWNlLCBidXQgdGhpc1xuXHQgKiBpcyBmYXN0ZXIgYW5kIHdvcmtpbmcgb24gYWxsIGFycmF5LWxpa2Ugb2JqZWN0cyAobGlrZSBhcmd1bWVudHMpLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGFyciBBcnJheS1saWtlIG9iamVjdCB0byBzbGljZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBpbmRleCB0aGF0IHNob3VsZCBzdGFydCB0aGUgc2xpY2UuXG5cdCAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIFRoZSBpbmRleCB3aGVyZSB0aGUgc2xpY2Ugc2hvdWxkIGVuZCwgbm90XG5cdCAqICAgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIGFycmF5LiBJZiBub3QgZ2l2ZW4sIGFsbCBlbGVtZW50cyBhZnRlciB0aGVcblx0ICogICBzdGFydCBpbmRleCB3aWxsIGJlIGluY2x1ZGVkLlxuXHQgKiBAcmV0dXJuIHshQXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc2xpY2UoYXJyLCBzdGFydCwgZW5kID0gYXJyLmxlbmd0aCkge1xuXHRcdGNvbnN0IHNsaWNlZCA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG5cdFx0XHRzbGljZWQucHVzaChhcnJbaV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gc2xpY2VkO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGFycmF5O1xuIiwiLyogIVxuICogUG9seWZpbGwgZnJvbSBHb29nbGUncyBDbG9zdXJlIExpYnJhcnkuXG4gKiBDb3B5cmlnaHQgMjAxMyBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2lzU2VydmVyU2lkZX0gZnJvbSAnLi4vY29yZU5hbWVkJztcblxuY29uc3QgYXN5bmMgPSB7fTtcblxuLyoqXG4gKiBUaHJvdyBhbiBpdGVtIHdpdGhvdXQgaW50ZXJydXB0aW5nIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LiAgRm9yXG4gKiBleGFtcGxlLCBpZiBwcm9jZXNzaW5nIGEgZ3JvdXAgb2YgaXRlbXMgaW4gYSBsb29wLCBzb21ldGltZXMgaXQgaXMgdXNlZnVsXG4gKiB0byByZXBvcnQgYW4gZXJyb3Igd2hpbGUgc3RpbGwgYWxsb3dpbmcgdGhlIHJlc3Qgb2YgdGhlIGJhdGNoIHRvIGJlXG4gKiBwcm9jZXNzZWQuXG4gKiBAcGFyYW0geyp9IGV4Y2VwdGlvblxuICovXG5hc3luYy50aHJvd0V4Y2VwdGlvbiA9IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuXHQvLyBFYWNoIHRocm93IG5lZWRzIHRvIGJlIGluIGl0cyBvd24gY29udGV4dC5cblx0YXN5bmMubmV4dFRpY2soZnVuY3Rpb24oKSB7XG5cdFx0dGhyb3cgZXhjZXB0aW9uO1xuXHR9KTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrIGp1c3QgYmVmb3JlIHRoZSBjdXJyZW50IGNhbGxzdGFjayB1bndpbmRzLCBvciBhc1xuICogc29vbiBhcyBwb3NzaWJsZSBhZnRlciB0aGUgY3VycmVudCBKUyBleGVjdXRpb24gY29udGV4dC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpUSElTKX0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7VEhJUz19IGNvbnRleHQgT2JqZWN0IHRvIHVzZSBhcyB0aGUgXCJ0aGlzIHZhbHVlXCIgd2hlbiBjYWxsaW5nXG4gKiAgICAgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uLlxuICogQHRlbXBsYXRlIFRISVNcbiAqL1xuYXN5bmMucnVuID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0aWYgKCFhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXykge1xuXHRcdC8vIE5vdGhpbmcgaXMgY3VycmVudGx5IHNjaGVkdWxlZCwgc2NoZWR1bGUgaXQgbm93LlxuXHRcdGFzeW5jLm5leHRUaWNrKGFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlKTtcblx0XHRhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IHRydWU7XG5cdH1cblxuXHRhc3luYy5ydW4ud29ya1F1ZXVlXy5wdXNoKG5ldyBhc3luYy5ydW4uV29ya0l0ZW1fKGNhbGxiYWNrLCBjb250ZXh0KSk7XG59O1xuXG4vKiogQHByaXZhdGUge2Jvb2xlYW59ICovXG5hc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IGZhbHNlO1xuXG4vKiogQHByaXZhdGUgeyFBcnJheS48IWFzeW5jLnJ1bi5Xb3JrSXRlbV8+fSAqL1xuYXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblxuLyoqXG4gKiBSdW4gYW55IHBlbmRpbmcgYXN5bmMucnVuIHdvcmsgaXRlbXMuIFRoaXMgZnVuY3Rpb24gaXMgbm90IGludGVuZGVkXG4gKiBmb3IgZ2VuZXJhbCB1c2UsIGJ1dCBmb3IgdXNlIGJ5IGVudHJ5IHBvaW50IGhhbmRsZXJzIHRvIHJ1biBpdGVtcyBhaGVhZCBvZlxuICogYXN5bmMubmV4dFRpY2suXG4gKi9cbmFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlID0gZnVuY3Rpb24oKSB7XG5cdC8vIE5PVEU6IGFkZGl0aW9uYWwgd29yayBxdWV1ZSBpdGVtcyBtYXkgYmUgcHVzaGVkIHdoaWxlIHByb2Nlc3NpbmcuXG5cdHdoaWxlIChhc3luYy5ydW4ud29ya1F1ZXVlXy5sZW5ndGgpIHtcblx0XHQvLyBEb24ndCBsZXQgdGhlIHdvcmsgcXVldWUgZ3JvdyBpbmRlZmluaXRlbHkuXG5cdFx0Y29uc3Qgd29ya0l0ZW1zID0gYXN5bmMucnVuLndvcmtRdWV1ZV87XG5cdFx0YXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHdvcmtJdGVtcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgd29ya0l0ZW0gPSB3b3JrSXRlbXNbaV07XG5cdFx0XHR0cnkge1xuXHRcdFx0XHR3b3JrSXRlbS5mbi5jYWxsKHdvcmtJdGVtLnNjb3BlKTtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0YXN5bmMudGhyb3dFeGNlcHRpb24oZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gVGhlcmUgYXJlIG5vIG1vcmUgd29yayBpdGVtcywgcmVzZXQgdGhlIHdvcmsgcXVldWUuXG5cdGFzeW5jLnJ1bi53b3JrUXVldWVTY2hlZHVsZWRfID0gZmFsc2U7XG59O1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICogQGZpbmFsXG4gKiBAc3RydWN0XG4gKiBAcHJpdmF0ZVxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gZm5cbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx8dW5kZWZpbmVkfSBzY29wZVxuICovXG5hc3luYy5ydW4uV29ya0l0ZW1fID0gZnVuY3Rpb24oZm4sIHNjb3BlKSB7XG5cdC8qKiBAY29uc3QgKi9cblx0dGhpcy5mbiA9IGZuO1xuXHQvKiogQGNvbnN0ICovXG5cdHRoaXMuc2NvcGUgPSBzY29wZTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrcyBhcyBzb29uIGFzIHBvc3NpYmxlIGFmdGVyIHRoZSBjdXJyZW50IEpTXG4gKiBleGVjdXRpb24gY29udGV4dC4gc2V0VGltZW91dCjigKYsIDApIGFsd2F5cyB0YWtlcyBhdCBsZWFzdCA1bXMgZm9yIGxlZ2FjeVxuICogcmVhc29ucy5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpTQ09QRSl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhc1xuICogICAgIHBvc3NpYmxlLlxuICogQHBhcmFtIHtTQ09QRT19IGNvbnRleHQgT2JqZWN0IGluIHdob3NlIHNjb3BlIHRvIGNhbGwgdGhlIGxpc3RlbmVyLlxuICogQHRlbXBsYXRlIFNDT1BFXG4gKi9cbmFzeW5jLm5leHRUaWNrID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0bGV0IGNiID0gY2FsbGJhY2s7XG5cdGlmIChjb250ZXh0KSB7XG5cdFx0Y2IgPSBjYWxsYmFjay5iaW5kKGNvbnRleHQpO1xuXHR9XG5cdGNiID0gYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyhjYik7XG5cdC8vIExvb2sgZm9yIGFuZCBjYWNoZSB0aGUgY3VzdG9tIGZhbGxiYWNrIHZlcnNpb24gb2Ygc2V0SW1tZWRpYXRlLlxuXHRpZiAoIWFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8pIHtcblx0XHRpZiAoXG5cdFx0XHR0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHRpc1NlcnZlclNpZGUoe2NoZWNrRW52OiBmYWxzZX0pXG5cdFx0KSB7XG5cdFx0XHRhc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfID0gc2V0SW1tZWRpYXRlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRcdGFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8gPSBhc3luYy5uZXh0VGljay5nZXRTZXRJbW1lZGlhdGVFbXVsYXRvcl8oKTtcblx0XHR9XG5cdH1cblx0YXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyhjYik7XG59O1xuXG4vKipcbiAqIENhY2hlIGZvciB0aGUgc2V0SW1tZWRpYXRlIGltcGxlbWVudGF0aW9uLlxuICogQHR5cGUge2Z1bmN0aW9uKGZ1bmN0aW9uKCkpfVxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyA9IG51bGw7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB0aGUgYmVzdCBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbiB0byBydW4gYSBmdW5jdGlvbiBhcyBzb29uIGFzXG4gKiB0aGUgSlMgZXZlbnQgbG9vcCBpcyBpZGxlLlxuICogQHJldHVybiB7ZnVuY3Rpb24oZnVuY3Rpb24oKSl9IFRoZSBcInNldEltbWVkaWF0ZVwiIGltcGxlbWVudGF0aW9uLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfID0gZnVuY3Rpb24oKSB7XG5cdC8vIENyZWF0ZSBhIHByaXZhdGUgbWVzc2FnZSBjaGFubmVsIGFuZCB1c2UgaXQgdG8gcG9zdE1lc3NhZ2UgZW1wdHkgbWVzc2FnZXNcblx0Ly8gdG8gb3Vyc2VsdmVzLlxuXHRsZXQgQ2hhbm5lbDtcblxuXHQvLyBWZXJpZnkgaWYgdmFyaWFibGUgaXMgZGVmaW5lZCBvbiB0aGUgY3VycmVudCBydW50aW1lIChpLmUuLCBub2RlLCBicm93c2VyKS5cblx0Ly8gQ2FuJ3QgdXNlIHR5cGVvZiBlbmNsb3NlZCBpbiBhIGZ1bmN0aW9uIChzdWNoIGFzIGNvcmUuaXNGdW5jdGlvbikgb3IgYW5cblx0Ly8gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBhbiBlbnZpcm9ubWVudFxuXHQvLyB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdW5kZWZpbmVkLlxuXHRpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0Q2hhbm5lbCA9IE1lc3NhZ2VDaGFubmVsO1xuXHR9XG5cblx0Ly8gSWYgTWVzc2FnZUNoYW5uZWwgaXMgbm90IGF2YWlsYWJsZSBhbmQgd2UgYXJlIGluIGEgYnJvd3NlciwgaW1wbGVtZW50XG5cdC8vIGFuIGlmcmFtZSBiYXNlZCBwb2x5ZmlsbCBpbiBicm93c2VycyB0aGF0IGhhdmUgcG9zdE1lc3NhZ2UgYW5kXG5cdC8vIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIuIFRoZSBsYXR0ZXIgZXhjbHVkZXMgSUU4IGJlY2F1c2UgaXQgaGFzIGFcblx0Ly8gc3luY2hyb25vdXMgcG9zdE1lc3NhZ2UgaW1wbGVtZW50YXRpb24uXG5cdGlmIChcblx0XHR0eXBlb2YgQ2hhbm5lbCA9PT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuXHRcdHdpbmRvdy5wb3N0TWVzc2FnZSAmJlxuXHRcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG5cdCkge1xuXHRcdC8qKiBAY29uc3RydWN0b3IgKi9cblx0XHRDaGFubmVsID0gZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBNYWtlIGFuIGVtcHR5LCBpbnZpc2libGUgaWZyYW1lLlxuXHRcdFx0Y29uc3QgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG5cdFx0XHRpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdGlmcmFtZS5zcmMgPSAnJztcblx0XHRcdGlmcmFtZS50aXRsZSA9ICcnO1xuXHRcdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKGlmcmFtZSk7XG5cdFx0XHRjb25zdCB3aW4gPSBpZnJhbWUuY29udGVudFdpbmRvdztcblx0XHRcdGNvbnN0IGRvYyA9IHdpbi5kb2N1bWVudDtcblx0XHRcdGRvYy5vcGVuKCk7XG5cdFx0XHRkb2Mud3JpdGUoJycpO1xuXHRcdFx0ZG9jLmNsb3NlKCk7XG5cdFx0XHRjb25zdCBtZXNzYWdlID0gJ2NhbGxJbW1lZGlhdGUnICsgTWF0aC5yYW5kb20oKTtcblx0XHRcdGNvbnN0IG9yaWdpbiA9IHdpbi5sb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyB3aW4ubG9jYXRpb24uaG9zdDtcblx0XHRcdGNvbnN0IG9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0Ly8gVmFsaWRhdGUgb3JpZ2luIGFuZCBtZXNzYWdlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSB3YXNcblx0XHRcdFx0Ly8gaW50ZW5kZWQgZm9yIHVzLlxuXHRcdFx0XHRpZiAoZS5vcmlnaW4gIT09IG9yaWdpbiAmJiBlLmRhdGEgIT09IG1lc3NhZ2UpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5wb3J0MS5vbm1lc3NhZ2UoKTtcblx0XHRcdH0uYmluZCh0aGlzKTtcblx0XHRcdHdpbi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25tZXNzYWdlLCBmYWxzZSk7XG5cdFx0XHR0aGlzLnBvcnQxID0ge307XG5cdFx0XHR0aGlzLnBvcnQyID0ge1xuXHRcdFx0XHRwb3N0TWVzc2FnZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0d2luLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIG9yaWdpbik7XG5cdFx0XHRcdH0sXG5cdFx0XHR9O1xuXHRcdH07XG5cdH1cblx0aWYgKHR5cGVvZiBDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuXHRcdGNvbnN0IGNoYW5uZWwgPSBuZXcgQ2hhbm5lbCgpO1xuXHRcdC8vIFVzZSBhIGZpZm8gbGlua2VkIGxpc3QgdG8gY2FsbCBjYWxsYmFja3MgaW4gdGhlIHJpZ2h0IG9yZGVyLlxuXHRcdGxldCBoZWFkID0ge307XG5cdFx0bGV0IHRhaWwgPSBoZWFkO1xuXHRcdGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRoZWFkID0gaGVhZC5uZXh0O1xuXHRcdFx0Y29uc3QgY2IgPSBoZWFkLmNiO1xuXHRcdFx0aGVhZC5jYiA9IG51bGw7XG5cdFx0XHRjYigpO1xuXHRcdH07XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0XHR0YWlsLm5leHQgPSB7XG5cdFx0XHRcdGNiOiBjYixcblx0XHRcdH07XG5cdFx0XHR0YWlsID0gdGFpbC5uZXh0O1xuXHRcdFx0Y2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcblx0XHR9O1xuXHR9XG5cdC8vIEltcGxlbWVudGF0aW9uIGZvciBJRTYtODogU2NyaXB0IGVsZW1lbnRzIGZpcmUgYW4gYXN5bmNocm9ub3VzXG5cdC8vIG9ucmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aGVuIGluc2VydGVkIGludG8gdGhlIERPTS5cblx0aWYgKFxuXHRcdHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHQnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKVxuXHQpIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oY2IpIHtcblx0XHRcdGxldCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRcdHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0Ly8gQ2xlYW4gdXAgYW5kIGNhbGwgdGhlIGNhbGxiYWNrLlxuXHRcdFx0XHRzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcblx0XHRcdFx0c2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcblx0XHRcdFx0c2NyaXB0ID0gbnVsbDtcblx0XHRcdFx0Y2IoKTtcblx0XHRcdFx0Y2IgPSBudWxsO1xuXHRcdFx0fTtcblx0XHRcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH07XG5cdH1cblx0Ly8gRmFsbCBiYWNrIHRvIHNldFRpbWVvdXQgd2l0aCAwLiBJbiBicm93c2VycyB0aGlzIGNyZWF0ZXMgYSBkZWxheSBvZiA1bXNcblx0Ly8gb3IgbW9yZS5cblx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0c2V0VGltZW91dChjYiwgMCk7XG5cdH07XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGlzIG92ZXJyaWRlZCB0byBwcm90ZWN0IGNhbGxiYWNrcyB3aXRoIGVudHJ5IHBvaW50XG4gKiBtb25pdG9yIGlmIHRoZSBhcHBsaWNhdGlvbiBtb25pdG9ycyBlbnRyeSBwb2ludHMuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhcyBwb3NzaWJsZS5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKCl9IFRoZSB3cmFwcGVkIGNhbGxiYWNrLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG5cdHJldHVybiBjYWxsYmFjaztcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIERpc3Bvc2FibGUgdXRpbGl0eS4gV2hlbiBpbmhlcml0ZWQgcHJvdmlkZXMgdGhlIGBkaXNwb3NlYCBmdW5jdGlvbiB0byBpdHNcbiAqIHN1YmNsYXNzLCB3aGljaCBpcyByZXNwb25zaWJsZSBmb3IgZGlzcG9zaW5nIG9mIGFueSBvYmplY3QgcmVmZXJlbmNlc1xuICogd2hlbiBhbiBpbnN0YW5jZSB3b24ndCBiZSB1c2VkIGFueW1vcmUuIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlXG4gKiBgZGlzcG9zZUludGVybmFsYCB0byBpbXBsZW1lbnQgYW55IHNwZWNpZmljIGRpc3Bvc2luZyBsb2dpYy5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5jbGFzcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIERpc3Bvc2FibGUgY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdC8qKlxuXHRcdCAqIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGluc3RhbmNlIGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZGlzcG9zZWRfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLiBDYWxscyBgZGlzcG9zZUludGVybmFsYC5cblx0ICovXG5cdGRpc3Bvc2UoKSB7XG5cdFx0aWYgKCF0aGlzLmRpc3Bvc2VkXykge1xuXHRcdFx0dGhpcy5kaXNwb3NlSW50ZXJuYWwoKTtcblx0XHRcdHRoaXMuZGlzcG9zZWRfID0gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gaW1wbGVtZW50IGFueSBzcGVjaWZpY1xuXHQgKiBkaXNwb3NpbmcgbG9naWMgKGxpa2UgY2xlYXJpbmcgcmVmZXJlbmNlcyBhbmQgY2FsbGluZyBgZGlzcG9zZWAgb24gb3RoZXJcblx0ICogZGlzcG9zYWJsZXMpLlxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge31cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoaXMgaW5zdGFuY2UgaGFzIGFscmVhZHkgYmVlbiBkaXNwb3NlZC5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzRGlzcG9zZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZGlzcG9zZWRfO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERpc3Bvc2FibGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3Igb2JqZWN0IG9wZXJhdGlvbnNcbiAqL1xuY2xhc3Mgb2JqZWN0IHtcblx0LyoqXG5cdCAqIENvcGllcyBhbGwgdGhlIG1lbWJlcnMgb2YgYSBzb3VyY2Ugb2JqZWN0IHRvIGEgdGFyZ2V0IG9iamVjdC5cblx0ICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUYXJnZXQgb2JqZWN0LlxuXHQgKiBAcGFyYW0gey4uLk9iamVjdH0gdmFyX2FyZ3MgVGhlIG9iamVjdHMgZnJvbSB3aGljaCB2YWx1ZXMgd2lsbCBiZSBjb3BpZWQuXG5cdCAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyB0aGUgdGFyZ2V0IG9iamVjdCByZWZlcmVuY2UuXG5cdCAqL1xuXHRzdGF0aWMgbWl4aW4odGFyZ2V0LCAuLi5hcmdzKSB7XG5cdFx0bGV0IGtleTtcblx0XHRsZXQgc291cmNlO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0c291cmNlID0gYXJnc1tpXTtcblx0XHRcdC8vIFBvc3NpYmxlIHByb3RvdHlwZSBjaGFpbiBsZWFrLCBicmVha3MgMSBtZXRhbC1kb20gYW5kXG5cdFx0XHQvLyAxIG1ldGFsLWluY3JlbWVudGFsLWRvbSB0ZXN0IGlmIGd1YXJkLWZvci1pbiBydWxlIGlzIGFkZHJlc3NlZFxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cdFx0XHRmb3IgKGtleSBpbiBzb3VyY2UpIHtcblx0XHRcdFx0dGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRhcmdldDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGFuIG9iamVjdCBiYXNlZCBvbiBpdHMgZnVsbHkgcXVhbGlmaWVkIGV4dGVybmFsIG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZS5cblx0ICogQHBhcmFtIHtvYmplY3Q9fSBzY29wZSBUaGUgb2JqZWN0IHdpdGhpbiB3aGljaCB0byBsb29rOyBkZWZhdWx0IGlzXG5cdCAqICAgICA8Y29kZT53aW5kb3c8L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHs/fSBUaGUgdmFsdWUgKG9iamVjdCBvciBwcmltaXRpdmUpIG9yLCBpZiBub3QgZm91bmQsIHVuZGVmaW5lZC5cblx0ICovXG5cdHN0YXRpYyBnZXRPYmplY3RCeU5hbWUobmFtZSwgc2NvcGUgPSB3aW5kb3cpIHtcblx0XHRjb25zdCBwYXJ0cyA9IG5hbWUuc3BsaXQoJy4nKTtcblx0XHRyZXR1cm4gcGFydHMucmVkdWNlKChwYXJ0LCBrZXkpID0+IHBhcnRba2V5XSwgc2NvcGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUga2V5cyBhcyB0aGUgZ2l2ZW4gb25lLCBidXQgd2l0aFxuXHQgKiB0aGVpciB2YWx1ZXMgc2V0IHRvIHRoZSByZXR1cm4gdmFsdWVzIG9mIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24uXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gb2JqXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKHN0cmluZywgKil9IGZuXG5cdCAqIEByZXR1cm4geyFPYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgbWFwKG9iaiwgZm4pIHtcblx0XHRjb25zdCBtYXBwZWRPYmogPSB7fTtcblx0XHRjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG1hcHBlZE9ialtrZXlzW2ldXSA9IGZuKGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXBwZWRPYmo7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSB0d28gZ2l2ZW4gb2JqZWN0cyBhcmUgZXF1YWwuIFRoaXMgaXMgZG9uZSB2aWEgYSBzaGFsbG93XG5cdCAqIGNoZWNrLCBpbmNsdWRpbmcgb25seSB0aGUga2V5cyBkaXJlY3RseSBjb250YWluZWQgYnkgdGhlIDIgb2JqZWN0cy5cblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajFcblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBzaGFsbG93RXF1YWwob2JqMSwgb2JqMikge1xuXHRcdGlmIChvYmoxID09PSBvYmoyKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBrZXlzMSA9IE9iamVjdC5rZXlzKG9iajEpO1xuXHRcdGNvbnN0IGtleXMyID0gT2JqZWN0LmtleXMob2JqMik7XG5cdFx0aWYgKGtleXMxLmxlbmd0aCAhPT0ga2V5czIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKG9iajFba2V5czFbaV1dICE9PSBvYmoyW2tleXMxW2ldXSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9iamVjdDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBzdHJpbmcgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBzdHJpbmcge1xuXHQvKipcblx0ICogQ29tcGFyZXMgdGhlIGdpdmVuIHN0cmluZ3Mgd2l0aG91dCB0YWtpbmcgdGhlIGNhc2UgaW50byBhY2NvdW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHN0cjFcblx0ICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdHIyXG5cdCAqIEByZXR1cm4ge251bWJlcn0gRWl0aGVyIC0xLCAwIG9yIDEsIGFjY29yZGluZyB0byBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzXG5cdCAqICAgICBcInNtYWxsZXJcIiwgZXF1YWwgb3IgXCJiaWdnZXJcIiB0aGFuIHRoZSBzZWNvbmQgZ2l2ZW4gc3RyaW5nLlxuXHQgKi9cblx0c3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbXBhcmUoc3RyMSwgc3RyMikge1xuXHRcdGNvbnN0IHRlc3QxID0gU3RyaW5nKHN0cjEpLnRvTG93ZXJDYXNlKCk7XG5cdFx0Y29uc3QgdGVzdDIgPSBTdHJpbmcoc3RyMikudG9Mb3dlckNhc2UoKTtcblxuXHRcdGlmICh0ZXN0MSA8IHRlc3QyKSB7XG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0fSBlbHNlIGlmICh0ZXN0MSA9PT0gdGVzdDIpIHtcblx0XHRcdHJldHVybiAwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgYnJlYWtpbmcgc3BhY2VzIGZyb20gdGhlIGxlZnQgYW5kIHJpZ2h0IG9mIHRoZSBzdHJpbmcgYW5kXG5cdCAqIGNvbGxhcHNlcyB0aGUgc2VxdWVuY2VzIG9mIGJyZWFraW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlIGludG8gc2luZ2xlIHNwYWNlcy5cblx0ICogVGhlIG9yaWdpbmFsIGFuZCB0aGUgcmVzdWx0IHN0cmluZ3MgcmVuZGVyIHRoZSBzYW1lIHdheSBpbiBIVE1MLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIEEgc3RyaW5nIGluIHdoaWNoIHRvIGNvbGxhcHNlIHNwYWNlcy5cblx0ICogQHJldHVybiB7c3RyaW5nfSBDb3B5IG9mIHRoZSBzdHJpbmcgd2l0aCBub3JtYWxpemVkIGJyZWFraW5nIHNwYWNlcy5cblx0ICovXG5cdHN0YXRpYyBjb2xsYXBzZUJyZWFraW5nU3BhY2VzKHN0cikge1xuXHRcdHJldHVybiBzdHJcblx0XHRcdC5yZXBsYWNlKC9bXFx0XFxyXFxuIF0rL2csICcgJylcblx0XHRcdC5yZXBsYWNlKC9eW1xcdFxcclxcbiBdK3xbXFx0XFxyXFxuIF0rJC9nLCAnJyk7XG5cdH1cblxuXHQvKipcblx0ICogRXNjYXBlcyBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcgdGhhdCBhcmUgbm90IHNhZmUgdG8gdXNlIGluIGEgUmVnRXhwLlxuXHQgKiBAcGFyYW0geyp9IHN0ciBUaGUgc3RyaW5nIHRvIGVzY2FwZS4gSWYgbm90IGEgc3RyaW5nLCBpdCB3aWxsIGJlIGNhc3RlZFxuXHQgKiAgICAgdG8gb25lLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEEgUmVnRXhwIHNhZmUsIGVzY2FwZWQgY29weSBvZiB7QGNvZGUgc30uXG5cdCAqL1xuXHRzdGF0aWMgZXNjYXBlUmVnZXgoc3RyKSB7XG5cdFx0cmV0dXJuIFN0cmluZyhzdHIpXG5cdFx0XHQucmVwbGFjZSgvKFstKClbXFxde30rPyouJF58LDojPCFcXFxcXSkvZywgJ1xcXFwkMScpXG5cdFx0XHQucmVwbGFjZSgvXFx4MDgvZywgJ1xcXFx4MDgnKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhdCBsZWFzdCA2NC1iaXRzIG9mIHJhbmRvbW5lc3MuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQSByYW5kb20gc3RyaW5nLCBlLmcuIHNuMXM3dmI0Z2NpYy5cblx0ICovXG5cdHN0YXRpYyBnZXRSYW5kb21TdHJpbmcoKSB7XG5cdFx0Y29uc3QgeCA9IDIxNDc0ODM2NDg7XG5cdFx0cmV0dXJuIChcblx0XHRcdE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHgpLnRvU3RyaW5nKDM2KSArXG5cdFx0XHRNYXRoLmFicyhNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB4KSBeIERhdGUubm93KCkpLnRvU3RyaW5nKDM2KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FsY3VsYXRlcyB0aGUgaGFzaGNvZGUgZm9yIGEgc3RyaW5nLiBUaGUgaGFzaGNvZGUgdmFsdWUgaXMgY29tcHV0ZWQgYnlcblx0ICogdGhlIHN1bSBhbGdvcml0aG06IHNbMF0qMzFeKG4tMSkgKyBzWzFdKjMxXihuLTIpICsgLi4uICsgc1tuLTFdLiBBIG5pY2Vcblx0ICogcHJvcGVydHkgb2YgdXNpbmcgMzEgcHJpbWUgaXMgdGhhdCB0aGUgbXVsdGlwbGljYXRpb24gY2FuIGJlIHJlcGxhY2VkIGJ5XG5cdCAqIGEgc2hpZnQgYW5kIGEgc3VidHJhY3Rpb24gZm9yIGJldHRlciBwZXJmb3JtYW5jZTogMzEqaSA9PSAoaTw8NSktaS5cblx0ICogTW9kZXJuIFZNcyBkbyB0aGlzIHNvcnQgb2Ygb3B0aW1pemF0aW9uIGF1dG9tYXRpY2FsbHkuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB2YWwgVGFyZ2V0IHN0cmluZy5cblx0ICogQHJldHVybiB7TnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgaGFzaGNvZGUuXG5cdCAqL1xuXHRzdGF0aWMgaGFzaENvZGUodmFsKSB7XG5cdFx0bGV0IGhhc2ggPSAwO1xuXHRcdGZvciAobGV0IGkgPSAwLCBsZW4gPSB2YWwubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGhhc2ggPSAzMSAqIGhhc2ggKyB2YWwuY2hhckNvZGVBdChpKTtcblx0XHRcdGhhc2ggJT0gMHgxMDAwMDAwMDA7XG5cdFx0fVxuXHRcdHJldHVybiBoYXNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlcGxhY2VzIGludGVydmFsIGludG8gdGhlIHN0cmluZyB3aXRoIHNwZWNpZmllZCB2YWx1ZSwgZS5nLlxuXHQgKiBgcmVwbGFjZUludGVydmFsKFwiYWJjZGVcIiwgMSwgNCwgXCJcIilgIHJldHVybnMgXCJhZVwiLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBpbnB1dCBzdHJpbmcuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydCBTdGFydCBpbnRlcnZhbCBwb3NpdGlvbiB0byBiZSByZXBsYWNlZC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IGVuZCBFbmQgaW50ZXJ2YWwgcG9zaXRpb24gdG8gYmUgcmVwbGFjZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdGhhdCByZXBsYWNlcyB0aGUgc3BlY2lmaWVkIGludGVydmFsLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgcmVwbGFjZUludGVydmFsKHN0ciwgc3RhcnQsIGVuZCwgdmFsdWUpIHtcblx0XHRyZXR1cm4gc3RyLnN1YnN0cmluZygwLCBzdGFydCkgKyB2YWx1ZSArIHN0ci5zdWJzdHJpbmcoZW5kKTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBzdHJpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7aXNEZWZ9IGZyb20gJ21ldGFsJztcblxuY29uc3QgTUVUQUxfREFUQSA9ICdfX21ldGFsX2RhdGFfXyc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3IgZG9tIGRhdGEgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBkb21EYXRhIHtcblx0LyoqXG5cdCAqIEdldHMgTWV0YWwuanMncyBkYXRhIGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuXHQgKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgT3B0aW9uYWwgcHJvcGVydHkgZnJvbSB0aGUgZGF0YSB0byBiZSByZXR1cm5lZC5cblx0ICogQHBhcmFtIHsqPX0gaW5pdGlhbFZhbHVlIE9wdGlvbmFsIHZhbHVlIHRvIHRoZSBzZXQgdGhlIHJlcXVlc3RlZCBwcm9wZXJ0eVxuXHQgKiAgICAgdG8gaWYgaXQgZG9lc24ndCBleGlzdCB5ZXQgaW4gdGhlIGRhdGEuXG5cdCAqIEByZXR1cm4geyFPYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgZ2V0KGVsZW1lbnQsIG5hbWUsIGluaXRpYWxWYWx1ZSkge1xuXHRcdGlmICghZWxlbWVudFtNRVRBTF9EQVRBXSkge1xuXHRcdFx0ZWxlbWVudFtNRVRBTF9EQVRBXSA9IHt9O1xuXHRcdH1cblx0XHRpZiAoIW5hbWUpIHtcblx0XHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdO1xuXHRcdH1cblx0XHRpZiAoIWlzRGVmKGVsZW1lbnRbTUVUQUxfREFUQV1bbmFtZV0pICYmIGlzRGVmKGluaXRpYWxWYWx1ZSkpIHtcblx0XHRcdGVsZW1lbnRbTUVUQUxfREFUQV1bbmFtZV0gPSBpbml0aWFsVmFsdWU7XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBoYXMgZGF0YSBzdG9yZWQgaW4gaXQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBoYXMoZWxlbWVudCkge1xuXHRcdHJldHVybiAhIWVsZW1lbnRbTUVUQUxfREFUQV07XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBNZXRhbC5qcydzIGRhdGEgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBmcm9tIHRoZSBkYXRhIHRvIGJlIHNldC5cblx0ICogQHBhcmFtIHsqPX0gdmFsdWUgVmFsdWUgdG8gYmUgc2V0IG9uIHRoZSBlbGVtZW50LlxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fCp9XG5cdCAqL1xuXHRzdGF0aWMgc2V0KGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG5cdFx0aWYgKCFlbGVtZW50W01FVEFMX0RBVEFdKSB7XG5cdFx0XHRlbGVtZW50W01FVEFMX0RBVEFdID0ge307XG5cdFx0fVxuXHRcdGlmICghbmFtZSB8fCAhaXNEZWYodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gZWxlbWVudFtNRVRBTF9EQVRBXTtcblx0XHR9XG5cdFx0ZWxlbWVudFtNRVRBTF9EQVRBXVtuYW1lXSA9IHZhbHVlO1xuXHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRvbURhdGE7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlIHV0aWxpdHkuIEhvbGRzIGluZm9ybWF0aW9uIGFib3V0IGFuIGV2ZW50IHN1YnNjcmlwdGlvbiwgYW5kXG4gKiBhbGxvd3MgcmVtb3ZpbmcgdGhlbSBlYXNpbHkuXG4gKiBFdmVudEhhbmRsZSBpcyBhIERpc3Bvc2FibGUsIGJ1dCBpdCdzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhlXG4gKiBFdmVudEVtaXR0ZXIgdGhhdCBjcmVhdGVkIGl0IGlzIG5vdCB0aGUgb25lIHJlc3BvbnNpYmxlIGZvciBkaXNwb3NpbmcgaXQuXG4gKiBUaGF0IHJlc3BvbnNpYmlsaXR5IGlzIGZvciB0aGUgY29kZSB0aGF0IGhvbGRzIGEgcmVmZXJlbmNlIHRvIGl0LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBFdmVudEhhbmRsZSBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IGVtaXR0ZXIgRW1pdHRlciB0aGUgZXZlbnQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdGhhdCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgRXZlbnRFbWl0dGVyIGluc3RhbmNlIHRoYXQgdGhlIGV2ZW50IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZW1pdHRlcl8gPSBlbWl0dGVyO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRoYXQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudF8gPSBldmVudDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0XHQgKiBAdHlwZSB7RnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubGlzdGVuZXJfID0gbGlzdGVuZXI7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0dGhpcy5lbWl0dGVyXyA9IG51bGw7XG5cdFx0dGhpcy5saXN0ZW5lcl8gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIHN1YnNjcmlwdGlvbiBmcm9tIHRoZSBlbWl0dGVyLlxuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0aWYgKCF0aGlzLmVtaXR0ZXJfLmlzRGlzcG9zZWQoKSkge1xuXHRcdFx0dGhpcy5lbWl0dGVyXy5yZW1vdmVMaXN0ZW5lcih0aGlzLmV2ZW50XywgdGhpcy5saXN0ZW5lcl8pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudEhhbmRsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcnJheSwgRGlzcG9zYWJsZSwgaXNGdW5jdGlvbiwgaXNTdHJpbmd9IGZyb20gJ21ldGFsJztcbmltcG9ydCBFdmVudEhhbmRsZSBmcm9tICcuL0V2ZW50SGFuZGxlJztcblxuY29uc3Qgc2luZ2xlQXJyYXlfID0gWzBdO1xuXG4vKipcbiAqIEV2ZW50RW1pdHRlciB1dGlsaXR5LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50RW1pdHRlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRFbWl0dGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgZXZlbnQgbGlzdGVuZXJzIHNjb3BlZCBieSBldmVudCB0eXBlLlxuXHRcdCAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAhQXJyYXk8IWZ1bmN0aW9uKCk+Pn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhhbmRsZXJzIHRoYXQgYXJlIHRyaWdnZXJlZCB3aGVuIGFuIGV2ZW50IGlzIGxpc3RlbmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtBcnJheX1cblx0XHQgKi9cblx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIENvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZCBiZSBzZW50XG5cdFx0ICogYXMgYSBwYXJhbSBvZiBsaXN0ZW5lcnMgd2hlbiBlbWl0dGluZyBldmVudHMuIElmIHNldCB0byB0cnVlLCB0aGUgZmFjYWRlXG5cdFx0ICogd2lsbCBiZSBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoZSBsaXN0ZW5lci5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zaG91bGRVc2VGYWNhZGVfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGhhbmRsZXIgdG8gZ2l2ZW4gaG9sZGVyIHZhcmlhYmxlLiBJZiB0aGUgaG9sZGVyIGRvZXNuJ3QgaGF2ZSBhXG5cdCAqIHZhbHVlIHlldCwgaXQgd2lsbCByZWNlaXZlIHRoZSBoYW5kbGVyIGRpcmVjdGx5LiBJZiB0aGUgaG9sZGVyIGlzIGFuIGFycmF5LFxuXHQgKiB0aGUgdmFsdWUgd2lsbCBqdXN0IGJlIGFkZGVkIHRvIGl0LiBPdGhlcndpc2UsIHRoZSBob2xkZXIgd2lsbCBiZSBzZXQgdG8gYVxuXHQgKiBuZXcgYXJyYXkgY29udGFpbmluZyBpdHMgcHJldmlvdXMgdmFsdWUgcGx1cyB0aGUgbmV3IGhhbmRsZXIuXG5cdCAqIEBwYXJhbSB7Kn0gaG9sZGVyXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl8T2JqZWN0fSBoYW5kbGVyXG5cdCAqIEByZXR1cm4geyp9IFRoZSBob2xkZXIncyBuZXcgdmFsdWUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGFkZEhhbmRsZXJfKGhvbGRlciwgaGFuZGxlcikge1xuXHRcdGlmICghaG9sZGVyKSB7XG5cdFx0XHRob2xkZXIgPSBoYW5kbGVyO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIUFycmF5LmlzQXJyYXkoaG9sZGVyKSkge1xuXHRcdFx0XHRob2xkZXIgPSBbaG9sZGVyXTtcblx0XHRcdH1cblx0XHRcdGhvbGRlci5wdXNoKGhhbmRsZXIpO1xuXHRcdH1cblx0XHRyZXR1cm4gaG9sZGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG5cdCAqL1xuXHRhZGRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcikge1xuXHRcdHRoaXMudmFsaWRhdGVMaXN0ZW5lcl8obGlzdGVuZXIpO1xuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50c1tpXSwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBFdmVudEhhbmRsZSh0aGlzLCBldmVudCwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIGEgc2luZ2xlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9uPX0gb3JpZ2luIFRoZSBvcmlnaW5hbCBmdW5jdGlvbiB0aGF0IHdhcyBhZGRlZCBhcyBhXG5cdCAqICAgbGlzdGVuZXIsIGlmIHRoZXJlIGlzIGFueS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lciwgZGVmYXVsdExpc3RlbmVyLCBvcmlnaW4pIHtcblx0XHR0aGlzLnJ1bkxpc3RlbmVySGFuZGxlcnNfKGV2ZW50KTtcblx0XHRpZiAoZGVmYXVsdExpc3RlbmVyIHx8IG9yaWdpbikge1xuXHRcdFx0bGlzdGVuZXIgPSB7XG5cdFx0XHRcdGRlZmF1bHQ6IGRlZmF1bHRMaXN0ZW5lcixcblx0XHRcdFx0Zm46IGxpc3RlbmVyLFxuXHRcdFx0XHRvcmlnaW46IG9yaWdpbixcblx0XHRcdH07XG5cdFx0fVxuXHRcdHRoaXMuZXZlbnRzXyA9IHRoaXMuZXZlbnRzXyB8fCB7fTtcblx0XHR0aGlzLmV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRIYW5kbGVyXyh0aGlzLmV2ZW50c19bZXZlbnRdLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGZhY2FkZSBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7T2JqZWN0fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRidWlsZEZhY2FkZV8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy5nZXRTaG91bGRVc2VGYWNhZGUoKSkge1xuXHRcdFx0Y29uc3QgZmFjYWRlID0ge1xuXHRcdFx0XHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0ZmFjYWRlLnByZXZlbnRlZERlZmF1bHQgPSB0cnVlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0YXJnZXQ6IHRoaXMsXG5cdFx0XHRcdHR5cGU6IGV2ZW50LFxuXHRcdFx0fTtcblx0XHRcdHJldHVybiBmYWNhZGU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeGVjdXRlIGVhY2ggb2YgdGhlIGxpc3RlbmVycyBpbiBvcmRlciB3aXRoIHRoZSBzdXBwbGllZCBhcmd1bWVudHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyp9IG9wdF9hcmdzIFthcmcxXSwgW2FyZzJdLCBbLi4uXVxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgZXZlbnQgaGFkIGxpc3RlbmVycywgZmFsc2Ugb3RoZXJ3aXNlLlxuXHQgKi9cblx0ZW1pdChldmVudCkge1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCk7XG5cdFx0aWYgKGxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRjb25zdCBhcmdzID0gYXJyYXkuc2xpY2UoYXJndW1lbnRzLCAxKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdHRoaXMucnVuTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGFyZ3MsIHRoaXMuYnVpbGRGYWNhZGVfKGV2ZW50KSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbGlzdGVuZXIgb2JqZWN0cyBmb3IgdGhlIGdpdmVuIGV2ZW50LCBpZiB0aGVyZSBhcmUgYW55LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRnZXRSYXdMaXN0ZW5lcnNfKGV2ZW50KSB7XG5cdFx0Y29uc3QgZGlyZWN0TGlzdGVuZXJzID0gdG9BcnJheSh0aGlzLmV2ZW50c18gJiYgdGhpcy5ldmVudHNfW2V2ZW50XSk7XG5cdFx0cmV0dXJuIGRpcmVjdExpc3RlbmVycy5jb25jYXQoXG5cdFx0XHR0b0FycmF5KHRoaXMuZXZlbnRzXyAmJiB0aGlzLmV2ZW50c19bJyonXSlcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Z2V0U2hvdWxkVXNlRmFjYWRlKCkge1xuXHRcdHJldHVybiB0aGlzLnNob3VsZFVzZUZhY2FkZV87XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgbGlzdGVuZXJzLlxuXHQgKi9cblx0bGlzdGVuZXJzKGV2ZW50KSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCkubWFwKFxuXHRcdFx0bGlzdGVuZXIgPT4gKGxpc3RlbmVyLmZuID8gbGlzdGVuZXIuZm4gOiBsaXN0ZW5lcilcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIGZpeGVkIG51bWJlciBvZiB0aW1lcyBmb3IgdGhlXG5cdCAqIGV2ZW50cy4gQWZ0ZXIgZWFjaCBldmVudCBpcyB0cmlnZ2VyZWQgdGhlIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZXMsIHRoZVxuXHQgKiBsaXN0ZW5lciBpcyByZW1vdmVkIGZvciBpdC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cblx0ICovXG5cdG1hbnkoZXZlbnQsIGFtb3VudCwgbGlzdGVuZXIpIHtcblx0XHRjb25zdCBldmVudHMgPSB0aGlzLnRvRXZlbnRzQXJyYXlfKGV2ZW50KTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5tYW55XyhldmVudHNbaV0sIGFtb3VudCwgbGlzdGVuZXIpO1xuXHRcdH1cblxuXHRcdHJldHVybiBuZXcgRXZlbnRIYW5kbGUodGhpcywgZXZlbnQsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgYSBmaXhlZCBudW1iZXIgb2YgdGltZXMgZm9yIGEgc2luZ2xlXG5cdCAqIGV2ZW50LiBBZnRlciB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWVzLCB0aGVcblx0ICogbGlzdGVuZXIgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG1hbnlfKGV2ZW50LCBhbW91bnQsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3Qgc2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoYW1vdW50IDw9IDApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKlxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGhhbmRsZXJJbnRlcm5hbCgpIHtcblx0XHRcdGlmICgtLWFtb3VudCA9PT0gMCkge1xuXHRcdFx0XHRzZWxmLnJlbW92ZUxpc3RlbmVyKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwpO1xuXHRcdFx0fVxuXHRcdFx0bGlzdGVuZXIuYXBwbHkoc2VsZiwgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdH1cblxuXHRcdHNlbGYuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwsIGZhbHNlLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGEgbGlzdGVuZXIgb2JqZWN0IG1hdGNoZXMgdGhlIGdpdmVuIGxpc3RlbmVyIGZ1bmN0aW9uLiBUbyBtYXRjaCxcblx0ICogaXQgbmVlZHMgdG8gZWl0aGVyIHBvaW50IHRvIHRoYXQgbGlzdGVuZXIgb3IgaGF2ZSBpdCBhcyBpdHMgb3JpZ2luLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGxpc3RlbmVyT2JqXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXRjaGVzTGlzdGVuZXJfKGxpc3RlbmVyT2JqLCBsaXN0ZW5lcikge1xuXHRcdGNvbnN0IGZuID0gbGlzdGVuZXJPYmouZm4gfHwgbGlzdGVuZXJPYmo7XG5cdFx0cmV0dXJuIChcblx0XHRcdGZuID09PSBsaXN0ZW5lciB8fFxuXHRcdFx0KGxpc3RlbmVyT2JqLm9yaWdpbiAmJiBsaXN0ZW5lck9iai5vcmlnaW4gPT09IGxpc3RlbmVyKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudFxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IU9iamVjdH0gUmV0dXJucyBlbWl0dGVyLCBzbyBjYWxscyBjYW4gYmUgY2hhaW5lZC5cblx0ICovXG5cdG9mZihldmVudCwgbGlzdGVuZXIpIHtcblx0XHR0aGlzLnZhbGlkYXRlTGlzdGVuZXJfKGxpc3RlbmVyKTtcblx0XHRpZiAoIXRoaXMuZXZlbnRzXykge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRzX1tldmVudHNbaV1dID0gdGhpcy5yZW1vdmVNYXRjaGluZ0xpc3RlbmVyT2Jqc18oXG5cdFx0XHRcdHRvQXJyYXkodGhpcy5ldmVudHNfW2V2ZW50c1tpXV0pLFxuXHRcdFx0XHRsaXN0ZW5lclxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50cy5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgaGFuZGxlciB0aGF0IGdldHMgdHJpZ2dlcmVkIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8gb24gdGhpc1xuXHQgKiBpbnN0YW5jZS5cblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gaGFuZGxlclxuXHQgKi9cblx0b25MaXN0ZW5lcihoYW5kbGVyKSB7XG5cdFx0dGhpcy5saXN0ZW5lckhhbmRsZXJzXyA9IHRoaXMuYWRkSGFuZGxlcl8oXG5cdFx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfLFxuXHRcdFx0aGFuZGxlclxuXHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudHMuIFRoaXMgbGlzdGVuZXIgaXMgaW52b2tlZCBvbmx5IHRoZVxuXHQgKiBuZXh0IHRpbWUgZWFjaCBldmVudCBpcyBmaXJlZCwgYWZ0ZXIgd2hpY2ggaXQgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b25jZShldmVudHMsIGxpc3RlbmVyKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFueShldmVudHMsIDEsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnRzLiBJdCdzIG5vdCBhIGdvb2Rcblx0ICogaWRlYSB0byByZW1vdmUgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZCBlbHNld2hlcmUgaW4gdGhlIGNvZGUsXG5cdCAqIGVzcGVjaWFsbHkgd2hlbiBpdCdzIG9uIGFuIGVtaXR0ZXIgdGhhdCB5b3UgZGlkbid0IGNyZWF0ZS5cblx0ICogQHBhcmFtIHsoQXJyYXl8c3RyaW5nKT19IGV2ZW50XG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnQpIHtcblx0XHRpZiAodGhpcy5ldmVudHNfKSB7XG5cdFx0XHRpZiAoZXZlbnQpIHtcblx0XHRcdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5ldmVudHNfW2V2ZW50c1tpXV0gPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmV2ZW50c18gPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lciBvYmplY3RzIGZyb20gdGhlIGdpdmVuIGFycmF5IHRoYXQgbWF0Y2ggdGhlIGdpdmVuXG5cdCAqIGxpc3RlbmVyIGZ1bmN0aW9uLlxuXHQgKiBAcGFyYW0ge0FycmF5LjxPYmplY3Q+fSBsaXN0ZW5lck9ianNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4ge0FycmF5LjxPYmplY3Q+fE9iamVjdH0gVGhlIG5ldyBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoaXMgZXZlbnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZU1hdGNoaW5nTGlzdGVuZXJPYmpzXyhsaXN0ZW5lck9ianMsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3QgZmluYWxMaXN0ZW5lcnMgPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVyT2Jqcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKCF0aGlzLm1hdGNoZXNMaXN0ZW5lcl8obGlzdGVuZXJPYmpzW2ldLCBsaXN0ZW5lcikpIHtcblx0XHRcdFx0ZmluYWxMaXN0ZW5lcnMucHVzaChsaXN0ZW5lck9ianNbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmluYWxMaXN0ZW5lcnMubGVuZ3RoID4gMCA/IGZpbmFsTGlzdGVuZXJzIDogbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGhhbmRsZXJzIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRydW5MaXN0ZW5lckhhbmRsZXJzXyhldmVudCkge1xuXHRcdGxldCBoYW5kbGVycyA9IHRoaXMubGlzdGVuZXJIYW5kbGVyc187XG5cdFx0aWYgKGhhbmRsZXJzKSB7XG5cdFx0XHRoYW5kbGVycyA9IHRvQXJyYXkoaGFuZGxlcnMpO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBoYW5kbGVycy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRoYW5kbGVyc1tpXShldmVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGdpdmVuIGxpc3RlbmVycy5cblx0ICogQHBhcmFtIHshQXJyYXl9IGxpc3RlbmVyc1xuXHQgKiBAcGFyYW0geyFBcnJheX0gYXJnc1xuXHQgKiBAcGFyYW0ge09iamVjdH0gZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJ1bkxpc3RlbmVyc18obGlzdGVuZXJzLCBhcmdzLCBmYWNhZGUpIHtcblx0XHRpZiAoZmFjYWRlKSB7XG5cdFx0XHRhcmdzLnB1c2goZmFjYWRlKTtcblx0XHR9XG5cblx0XHRjb25zdCBkZWZhdWx0TGlzdGVuZXJzID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldLmZuIHx8IGxpc3RlbmVyc1tpXTtcblx0XHRcdGlmIChsaXN0ZW5lcnNbaV0uZGVmYXVsdCkge1xuXHRcdFx0XHRkZWZhdWx0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICghZmFjYWRlIHx8ICFmYWNhZGUucHJldmVudGVkRGVmYXVsdCkge1xuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBkZWZhdWx0TGlzdGVuZXJzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdGRlZmF1bHRMaXN0ZW5lcnNbal0uYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFVzZUZhY2FkZVxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fSBSZXR1cm5zIGVtaXR0ZXIsIHNvIGNhbGxzIGNhbiBiZSBjaGFpbmVkLlxuXHQgKi9cblx0c2V0U2hvdWxkVXNlRmFjYWRlKHNob3VsZFVzZUZhY2FkZSkge1xuXHRcdHRoaXMuc2hvdWxkVXNlRmFjYWRlXyA9IHNob3VsZFVzZUZhY2FkZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyB0aGUgcGFyYW1ldGVyIHRvIGFuIGFycmF5IGlmIG9ubHkgb25lIGV2ZW50IGlzIGdpdmVuLiBSZXVzZXMgdGhlXG5cdCAqIHNhbWUgYXJyYXkgZWFjaCB0aW1lIHRoaXMgY29udmVyc2lvbiBpcyBkb25lLCB0byBhdm9pZCB1c2luZyBtb3JlIG1lbW9yeVxuXHQgKiB0aGFuIG5lY2Vzc2FyeS5cblx0ICogQHBhcmFtICB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0b0V2ZW50c0FycmF5XyhldmVudHMpIHtcblx0XHRpZiAoaXNTdHJpbmcoZXZlbnRzKSkge1xuXHRcdFx0c2luZ2xlQXJyYXlfWzBdID0gZXZlbnRzO1xuXHRcdFx0ZXZlbnRzID0gc2luZ2xlQXJyYXlfO1xuXHRcdH1cblx0XHRyZXR1cm4gZXZlbnRzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbGlzdGVuZXIgaXMgdmFsaWQsIHRocm93aW5nIGFuIGV4Y2VwdGlvbiB3aGVuIGl0J3Mgbm90LlxuXHQgKiBAcGFyYW0gIHsqfSBsaXN0ZW5lclxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR2YWxpZGF0ZUxpc3RlbmVyXyhsaXN0ZW5lcikge1xuXHRcdGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIENvbnZlcnRzIHRvIGFuIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gdmFsXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdG9BcnJheSh2YWwpIHtcblx0dmFsID0gdmFsIHx8IFtdO1xuXHRyZXR1cm4gQXJyYXkuaXNBcnJheSh2YWwpID8gdmFsIDogW3ZhbF07XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50RW1pdHRlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtEaXNwb3NhYmxlfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogRXZlbnRFbWl0dGVyUHJveHkgdXRpbGl0eS4gSXQncyByZXNwb25zaWJsZSBmb3IgbGlua2luZyB0d28gRXZlbnRFbWl0dGVyXG4gKiBpbnN0YW5jZXMgdG9nZXRoZXIsIGVtaXR0aW5nIGV2ZW50cyBmcm9tIHRoZSBmaXJzdCBlbWl0dGVyIHRocm91Z2ggdGhlXG4gKiBzZWNvbmQgb25lLiBUaGF0IG1lYW5zIHRoYXQgbGlzdGVuaW5nIHRvIGEgc3VwcG9ydGVkIGV2ZW50IG9uIHRoZSB0YXJnZXRcbiAqIGVtaXR0ZXIgd2lsbCBtZWFuIGxpc3RlbmluZyB0byBpdCBvbiB0aGUgb3JpZ2luIGVtaXR0ZXIgYXMgd2VsbC5cbiAqIEBleHRlbmRzIHtEaXNwb3NhYmxlfVxuICovXG5jbGFzcyBFdmVudEVtaXR0ZXJQcm94eSBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXIgRXZlbnRzIG9yaWdpbmF0ZWQgb24gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYmUgZmlyZWQgZm9yIHRoZSB0YXJnZXQgZW1pdHRlcidzIGxpc3RlbmVycyBhcyB3ZWxsLlxuXHQgKiBAcGFyYW0ge0V2ZW50RW1pdHRlcn0gdGFyZ2V0RW1pdHRlciBFdmVudCBsaXN0ZW5lcnMgYXR0YWNoZWQgdG8gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYWxzbyBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgZXZlbnQgaXMgZmlyZWQgYnkgdGhlIG9yaWdpbiBlbWl0dGVyLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gYmxhY2tsaXN0IE9wdGlvbmFsIGJsYWNrbGlzdCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlXG5cdCAqIHByb3hpZWQuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB3aGl0ZWxpc3Rcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9yaWdpbkVtaXR0ZXIsIHRhcmdldEVtaXR0ZXIsIGJsYWNrbGlzdCwgd2hpdGVsaXN0KSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ibGFja2xpc3RfID0gYmxhY2tsaXN0O1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG9yaWdpbiBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIncyBldmVudHMgd2lsbCBiZSBwcm94aWVkIHRocm91Z2ggdGhlXG5cdFx0ICogdGFyZ2V0IGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBBIGxpc3Qgb2YgZXZlbnRzIHRoYXQgYXJlIHBlbmRpbmcgdG8gYmUgbGlzdGVuZWQgYnkgYW4gYWN0dWFsIG9yaWdpblxuXHRcdCAqIGVtaXR0ZXIuIEV2ZW50cyBhcmUgc3RvcmVkIGhlcmUgd2hlbiB0aGUgb3JpZ2luIGRvZXNuJ3QgZXhpc3QsIHNvIHRoZXlcblx0XHQgKiBjYW4gYmUgc2V0IG9uIGEgbmV3IG9yaWdpbiB3aGVuIG9uZSBpcyBzZXQuXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBlbmRpbmdFdmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGEgbWFwIG9mIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gZW1pdHRlciB0aGF0IGFyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdDxzdHJpbmcsICFFdmVudEhhbmRsZT59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucHJveGllZEV2ZW50c18gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIHRhcmdldCBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIgd2lsbCBlbWl0IGFsbCBldmVudHMgdGhhdCBjb21lIGZyb21cblx0XHQgKiB0aGUgb3JpZ2luIGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy50YXJnZXRFbWl0dGVyXyA9IHRhcmdldEVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBNYXAgb2YgZXZlbnRzIHRoYXQgc2hvdWxkIGJlIHByb3hpZWQuIElmIHdoaXRlbGlzdCBpcyBzZXQgYmxhY2tsaXN0IGlzIGlnbm9yZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy53aGl0ZWxpc3RfID0gd2hpdGVsaXN0O1xuXG5cdFx0dGhpcy5zdGFydFByb3h5XygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIGdpdmVuIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IFRoZSBsaXN0ZW5lZCBldmVudCdzIGhhbmRsZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHJldHVybiB0aGlzLm9yaWdpbkVtaXR0ZXJfLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyc18oKTtcblx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfID0gbnVsbDtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbWl0cyB0aGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUgb24gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRlbWl0T25UYXJnZXRfKC4uLmFyZ3MpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLmVtaXQoLi4uYXJncyk7XG5cdH1cblxuXHQvKipcblx0ICogUHJveGllcyB0aGUgZ2l2ZW4gZXZlbnQgZnJvbSB0aGUgb3JpZ2luIHRvIHRoZSB0YXJnZXQgZW1pdHRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqL1xuXHRwcm94eUV2ZW50KGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuc2hvdWxkUHJveHlFdmVudF8oZXZlbnQpKSB7XG5cdFx0XHR0aGlzLnRyeVRvQWRkTGlzdGVuZXJfKGV2ZW50KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgcHJveHkgbGlzdGVuZXIgZm9yIGFsbCBldmVudHMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZUxpc3RlbmVyc18oKSB7XG5cdFx0aWYgKHRoaXMucHJveGllZEV2ZW50c18pIHtcblx0XHRcdGNvbnN0IGV2ZW50cyA9IE9iamVjdC5rZXlzKHRoaXMucHJveGllZEV2ZW50c18pO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0dGhpcy5wcm94aWVkRXZlbnRzX1tldmVudHNbaV1dLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR9XG5cdFx0dGhpcy5wZW5kaW5nRXZlbnRzXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQ2hhbmdlcyB0aGUgb3JpZ2luIGVtaXR0ZXIuIFRoaXMgYXV0b21hdGljYWxseSBkZXRhY2hlcyBhbnkgZXZlbnRzIHRoYXRcblx0ICogd2VyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQgZnJvbSB0aGUgcHJldmlvdXMgZW1pdHRlciwgYW5kIHN0YXJ0cyBwcm94eWluZ1xuXHQgKiB0aGVtIG9uIHRoZSBuZXcgZW1pdHRlciBpbnN0ZWFkLlxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXJcblx0ICovXG5cdHNldE9yaWdpbkVtaXR0ZXIob3JpZ2luRW1pdHRlcikge1xuXHRcdGNvbnN0IGV2ZW50cyA9XG5cdFx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfICYmIHRoaXMucHJveGllZEV2ZW50c19cblx0XHRcdFx0PyBPYmplY3Qua2V5cyh0aGlzLnByb3hpZWRFdmVudHNfKVxuXHRcdFx0XHQ6IHRoaXMucGVuZGluZ0V2ZW50c187XG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cdFx0aWYgKGV2ZW50cykge1xuXHRcdFx0dGhpcy5yZW1vdmVMaXN0ZW5lcnNfKCk7XG5cdFx0XHRldmVudHMuZm9yRWFjaChldmVudCA9PiB0aGlzLnByb3h5RXZlbnQoZXZlbnQpKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBzaG91bGQgYmUgcHJveGllZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHNob3VsZFByb3h5RXZlbnRfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMud2hpdGVsaXN0XyAmJiAhdGhpcy53aGl0ZWxpc3RfW2V2ZW50XSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAodGhpcy5ibGFja2xpc3RfICYmIHRoaXMuYmxhY2tsaXN0X1tldmVudF0pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuICF0aGlzLnByb3hpZWRFdmVudHNfIHx8ICF0aGlzLnByb3hpZWRFdmVudHNfW2V2ZW50XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgcHJveHlpbmcgYWxsIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gdG8gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzdGFydFByb3h5XygpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLm9uTGlzdGVuZXIodGhpcy5wcm94eUV2ZW50LmJpbmQodGhpcykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgb3JpZ2luIGVtaXR0ZXIsIGlmIGl0IGV4aXN0cy4gT3RoZXJ3aXNlLCBzdG9yZXNcblx0ICogdGhlIHBlbmRpbmcgbGlzdGVuZXIgc28gaXQgY2FuIGJlIHVzZWQgb24gYSBmdXR1cmUgb3JpZ2luIGVtaXR0ZXIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0cnlUb0FkZExpc3RlbmVyXyhldmVudCkge1xuXHRcdGlmICh0aGlzLm9yaWdpbkVtaXR0ZXJfKSB7XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gdGhpcy5wcm94aWVkRXZlbnRzXyB8fCB7fTtcblx0XHRcdHRoaXMucHJveGllZEV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRMaXN0ZW5lcl8oXG5cdFx0XHRcdGV2ZW50LFxuXHRcdFx0XHR0aGlzLmVtaXRPblRhcmdldF8uYmluZCh0aGlzLCBldmVudClcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucGVuZGluZ0V2ZW50c18gPSB0aGlzLnBlbmRpbmdFdmVudHNfIHx8IFtdO1xuXHRcdFx0dGhpcy5wZW5kaW5nRXZlbnRzXy5wdXNoKGV2ZW50KTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRFbWl0dGVyUHJveHk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlciB1dGlsaXR5LiBJdCdzIHVzZWZ1bCBmb3IgZWFzaWx5IHJlbW92aW5nIGEgZ3JvdXAgb2ZcbiAqIGxpc3RlbmVycyBmcm9tIGRpZmZlcmVudCBFdmVudEVtaXR0ZXIgaW5zdGFuY2VzLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRIYW5kbGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogQW4gYXJyYXkgdGhhdCBob2xkcyB0aGUgYWRkZWQgZXZlbnQgaGFuZGxlcywgc28gdGhlIGxpc3RlbmVycyBjYW4gYmVcblx0XHQgKiByZW1vdmVkIGxhdGVyLlxuXHRcdCAqIEB0eXBlIHtBcnJheS48RXZlbnRIYW5kbGU+fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGV2ZW50IGhhbmRsZXMgdG8gYmUgcmVtb3ZlZCBsYXRlciB0aHJvdWdoIHRoZSBgcmVtb3ZlQWxsTGlzdGVuZXJzYFxuXHQgKiBtZXRob2QuXG5cdCAqIEBwYXJhbSB7Li4uKCFFdmVudEhhbmRsZSl9IHZhcl9hcmdzXG5cdCAqL1xuXHRhZGQoLi4uYXJncykge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmV2ZW50SGFuZGxlc18ucHVzaChhcmdzW2ldKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyB0aGF0IGhhdmUgYmVlbiBhZGRlZCB0aHJvdWdoIHRoZSBgYWRkYCBtZXRob2QuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmV2ZW50SGFuZGxlc18ubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRIYW5kbGVzX1tpXS5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdH1cblxuXHRcdHRoaXMuZXZlbnRIYW5kbGVzXyA9IFtdO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50SGFuZGxlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcnJheSwgaXNTdHJpbmd9IGZyb20gJ21ldGFsJztcbmltcG9ydCBkb21EYXRhIGZyb20gJy4vZG9tRGF0YSc7XG5pbXBvcnQge0V2ZW50SGFuZGxlfSBmcm9tICdtZXRhbC1ldmVudHMnO1xuXG4vKipcbiAqIFRoaXMgaXMgYSBzcGVjaWFsIEV2ZW50SGFuZGxlLCB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciBkb20gZGVsZWdhdGVkIGV2ZW50c1xuICogKG9ubHkgdGhlIG9uZXMgdGhhdCByZWNlaXZlIGEgdGFyZ2V0IGVsZW1lbnQsIG5vdCBhIHNlbGVjdG9yIHN0cmluZykuXG4gKiBAZXh0ZW5kcyB7RXZlbnRIYW5kbGV9XG4gKi9cbmNsYXNzIERvbURlbGVnYXRlZEV2ZW50SGFuZGxlIGV4dGVuZHMgRXZlbnRIYW5kbGUge1xuXHQvKipcblx0ICogVGhlIGNvbnN0cnVjdG9yIGZvciBgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGVgLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZW1pdHRlciBFbGVtZW50IHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZz19IHNlbGVjdG9yIEFuIG9wdGlvbmFsIHNlbGVjdG9yIHVzZWQgd2hlbiBkZWxlZ2F0aW5nXG5cdCAqICAgICB0aGUgZXZlbnQuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoZW1pdHRlciwgZXZlbnQsIGxpc3RlbmVyLCBzZWxlY3Rvcikge1xuXHRcdHN1cGVyKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lcik7XG5cdFx0dGhpcy5zZWxlY3Rvcl8gPSBzZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0Y29uc3QgZGVsZWdhdGluZyA9IGRvbURhdGEuZ2V0KHRoaXMuZW1pdHRlcl8sICdkZWxlZ2F0aW5nJywge30pO1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IGRvbURhdGEuZ2V0KHRoaXMuZW1pdHRlcl8sICdsaXN0ZW5lcnMnLCB7fSk7XG5cdFx0Y29uc3Qgc2VsZWN0b3IgPSB0aGlzLnNlbGVjdG9yXztcblx0XHRjb25zdCBhcnIgPSBpc1N0cmluZyhzZWxlY3Rvcilcblx0XHRcdD8gZGVsZWdhdGluZ1t0aGlzLmV2ZW50X10uc2VsZWN0b3JzXG5cdFx0XHQ6IGxpc3RlbmVycztcblx0XHRjb25zdCBrZXkgPSBpc1N0cmluZyhzZWxlY3RvcikgPyBzZWxlY3RvciA6IHRoaXMuZXZlbnRfO1xuXG5cdFx0YXJyYXkucmVtb3ZlKGFycltrZXldIHx8IFtdLCB0aGlzLmxpc3RlbmVyXyk7XG5cdFx0aWYgKGFycltrZXldICYmIGFycltrZXldLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0ZGVsZXRlIGFycltrZXldO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtFdmVudEhhbmRsZX0gZnJvbSAnbWV0YWwtZXZlbnRzJztcblxuLyoqXG4gKiBUaGlzIGlzIGEgc3BlY2lhbCBFdmVudEhhbmRsZSwgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgZG9tIGV2ZW50cywgaW5zdGVhZFxuICogb2YgRXZlbnRFbWl0dGVyIGV2ZW50cy5cbiAqIEBleHRlbmRzIHtFdmVudEhhbmRsZX1cbiAqL1xuY2xhc3MgRG9tRXZlbnRIYW5kbGUgZXh0ZW5kcyBFdmVudEhhbmRsZSB7XG5cdC8qKlxuXHQgKiBUaGUgY29uc3RydWN0b3IgZm9yIGBEb21FdmVudEhhbmRsZWAuXG5cdCAqIEBwYXJhbSB7IUV2ZW50RW1pdHRlcn0gZW1pdHRlciBFbWl0dGVyIHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGNhcHR1cmUgRmxhZyBpbmRpY2F0aW5nIGlmIGxpc3RlbmVyIHNob3VsZCBiZSB0cmlnZ2VyZWRcblx0ICogICBkdXJpbmcgY2FwdHVyZSBwaGFzZSwgaW5zdGVhZCBvZiBkdXJpbmcgdGhlIGJ1YmJsaW5nIHBoYXNlLiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIsIGNhcHR1cmUpIHtcblx0XHRzdXBlcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIpO1xuXHRcdHRoaXMuY2FwdHVyZV8gPSBjYXB0dXJlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHR0aGlzLmVtaXR0ZXJfLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG5cdFx0XHR0aGlzLmV2ZW50Xyxcblx0XHRcdHRoaXMubGlzdGVuZXJfLFxuXHRcdFx0dGhpcy5jYXB0dXJlX1xuXHRcdCk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRG9tRXZlbnRIYW5kbGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7XG5cdGlzRGVmLFxuXHRpc0RlZkFuZE5vdE51bGwsXG5cdGlzRG9jdW1lbnQsXG5cdGlzRG9jdW1lbnRGcmFnbWVudCxcblx0aXNFbGVtZW50LFxuXHRpc09iamVjdCxcblx0aXNTdHJpbmcsXG5cdG9iamVjdCxcbn0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IGRvbURhdGEgZnJvbSAnLi9kb21EYXRhJztcbmltcG9ydCBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZSBmcm9tICcuL0RvbURlbGVnYXRlZEV2ZW50SGFuZGxlJztcbmltcG9ydCBEb21FdmVudEhhbmRsZSBmcm9tICcuL0RvbUV2ZW50SGFuZGxlJztcblxuY29uc3QgZWxlbWVudHNCeVRhZ18gPSB7fTtcbmNvbnN0IHN1cHBvcnRDYWNoZV8gPSB7fTtcbmV4cG9ydCBjb25zdCBjdXN0b21FdmVudHMgPSB7fTtcblxuY29uc3QgTEFTVF9DT05UQUlORVIgPSAnX19tZXRhbF9sYXN0X2NvbnRhaW5lcl9fJztcbmNvbnN0IFVTRV9DQVBUVVJFID0ge1xuXHRibHVyOiB0cnVlLFxuXHRlcnJvcjogdHJ1ZSxcblx0Zm9jdXM6IHRydWUsXG5cdGludmFsaWQ6IHRydWUsXG5cdGxvYWQ6IHRydWUsXG5cdHNjcm9sbDogdHJ1ZSxcbn07XG5cbi8qKlxuICogQWRkcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIHRvIGFuIGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fCFOb2RlbGlzdH0gZWxlbWVudHMgVGhlIGVsZW1lbnQgb3IgZWxlbWVudHMgdG8gYWRkIENTUyBjbGFzc2VzIHRvLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gYWRkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkQ2xhc3NlcyhlbGVtZW50cywgY2xhc3Nlcykge1xuXHRpZiAoIWlzT2JqZWN0KGVsZW1lbnRzKSB8fCAhaXNTdHJpbmcoY2xhc3NlcykpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuXHRcdGVsZW1lbnRzID0gW2VsZW1lbnRzXTtcblx0fVxuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoJ2NsYXNzTGlzdCcgaW4gZWxlbWVudHNbaV0pIHtcblx0XHRcdGFkZENsYXNzZXNXaXRoTmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFkZENsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIHRvIGFuIGVsZW1lbnQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBhZGQgQ1NTIGNsYXNzZXMgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byBhZGQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRpZiAoY2xhc3NOYW1lKSB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcblx0XHR9XG5cdH0pO1xufVxuXG4vKipcbiAqIElFMTEgZG9lc24ndCBzdXBwb3J0IEVsZW1lbnQuY2xhc3NMaXN0LmFkZCBmdW5jdGlvbiwgdGhpcyBtZXRob2RcbiAqIGFkZHMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyB0byBhbiBlbGVtZW50IHdpdGhvdXQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBhZGQgQ1NTIGNsYXNzZXMgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byBhZGQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRDbGFzc2VzV2l0aG91dE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjb25zdCBlbGVtZW50Q2xhc3NOYW1lID0gYCAke2VsZW1lbnQuY2xhc3NOYW1lfSBgO1xuXHRsZXQgY2xhc3Nlc1RvQXBwZW5kID0gJyc7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRjb25zdCBjbGFzc05hbWUgPSBjbGFzc2VzW2ldO1xuXG5cdFx0aWYgKGVsZW1lbnRDbGFzc05hbWUuaW5kZXhPZihgICR7Y2xhc3NOYW1lfSBgKSA9PT0gLTEpIHtcblx0XHRcdGNsYXNzZXNUb0FwcGVuZCArPSBgICR7Y2xhc3NOYW1lfWA7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGNsYXNzZXNUb0FwcGVuZCkge1xuXHRcdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWUgKyBjbGFzc2VzVG9BcHBlbmQ7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIGFuIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBnaXZlbiBlbGVtZW50LCB0byBiZSB0cmlnZ2VyZWQgdmlhIGRlbGVnYXRlLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gbGlzdGVuZXJcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGFkZEVsZW1lbnRMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBsaXN0ZW5lcikge1xuXHRhZGRUb0Fycl8oZG9tRGF0YS5nZXQoZWxlbWVudCwgJ2xpc3RlbmVycycsIHt9KSwgZXZlbnROYW1lLCBsaXN0ZW5lcik7XG59XG5cbi8qKlxuICogQWRkcyBhbiBldmVudCBsaXN0ZW5lciB0byB0aGUgZ2l2ZW4gZWxlbWVudCwgdG8gYmUgdHJpZ2dlcmVkIHZpYSBkZWxlZ2F0ZVxuICogc2VsZWN0b3JzLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYWRkU2VsZWN0b3JMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3RvciwgbGlzdGVuZXIpIHtcblx0Y29uc3QgZGVsZWdhdGluZ0RhdGEgPSBkb21EYXRhLmdldChlbGVtZW50LCAnZGVsZWdhdGluZycsIHt9KTtcblx0YWRkVG9BcnJfKGRlbGVnYXRpbmdEYXRhW2V2ZW50TmFtZV0uc2VsZWN0b3JzLCBzZWxlY3RvciwgbGlzdGVuZXIpO1xufVxuXG4vKipcbiAqIEFkZHMgYSB2YWx1ZSB0byBhbiBhcnJheSBpbnNpZGUgYW4gb2JqZWN0LCBjcmVhdGluZyBpdCBmaXJzdCBpZiBpdCBkb2Vzbid0XG4gKiB5ZXQgZXhpc3QuXG4gKiBAcGFyYW0geyFBcnJheX0gYXJyXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRUb0Fycl8oYXJyLCBrZXksIHZhbHVlKSB7XG5cdGlmICghYXJyW2tleV0pIHtcblx0XHRhcnJba2V5XSA9IFtdO1xuXHR9XG5cdGFycltrZXldLnB1c2godmFsdWUpO1xufVxuXG4vKipcbiAqIEF0dGFjaGVzIGEgZGVsZWdhdGUgbGlzdGVuZXIsIHVubGVzcyB0aGVyZSdzIGFscmVhZHkgb25lIGF0dGFjaGVkLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYXR0YWNoRGVsZWdhdGVFdmVudF8oZWxlbWVudCwgZXZlbnROYW1lKSB7XG5cdGxldCBkZWxlZ2F0aW5nRGF0YSA9IGRvbURhdGEuZ2V0KGVsZW1lbnQsICdkZWxlZ2F0aW5nJywge30pO1xuXHRpZiAoIWRlbGVnYXRpbmdEYXRhW2V2ZW50TmFtZV0pIHtcblx0XHRkZWxlZ2F0aW5nRGF0YVtldmVudE5hbWVdID0ge1xuXHRcdFx0aGFuZGxlOiBvbihcblx0XHRcdFx0ZWxlbWVudCxcblx0XHRcdFx0ZXZlbnROYW1lLFxuXHRcdFx0XHRoYW5kbGVEZWxlZ2F0ZUV2ZW50Xyxcblx0XHRcdFx0ISFVU0VfQ0FQVFVSRVtldmVudE5hbWVdXG5cdFx0XHQpLFxuXHRcdFx0c2VsZWN0b3JzOiB7fSxcblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogSUUxMSBkb2Vzbid0IHN1cHBvcnQgRWxlbWVudC5jbG9zZXN0IGZ1bmN0aW9uLCB0aGlzIG1ldGhvZFxuICogZ2V0cyB0aGUgY2xvc2VzdCBlbGVtZW50IHVwIHRoZSB0cmVlIGZyb20gdGhlIGdpdmVuIGVsZW1lbnQgKGluY2x1ZGluZ1xuICogaXRzZWxmKSB0aGF0IG1hdGNoZXMgdGhlIHNwZWNpZmllZCBzZWxlY3Rvciwgb3IgbnVsbCBpZiBub25lIG1hdGNoLlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZXN0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XG5cdHdoaWxlIChlbGVtZW50ICYmICFtYXRjaChlbGVtZW50LCBzZWxlY3RvcikpIHtcblx0XHRlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXHR9XG5cdHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIElFMTEgZG9lc24ndCBzdXBwb3J0IEVsZW1lbnQuY2xhc3NMaXN0LmFkZCBmdW5jdGlvbiwgdGhpcyBtZXRob2RcbiAqIGFwcGVuZHMgYSBjaGlsZCBub2RlIHdpdGggdGV4dCBvciBvdGhlciBub2RlcyB0byBhIHBhcmVudCBub2RlLiBJZlxuICogY2hpbGQgaXMgYSBIVE1MIHN0cmluZyBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIGEgZG9jdW1lbnRcbiAqIGZyYWdtZW50IGJlZm9yZSBhcHBlbmRpbmcgaXQgdG8gdGhlIHBhcmVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IHBhcmVudCBUaGUgbm9kZSB0byBhcHBlbmQgbm9kZXMgdG8uXG4gKiBAcGFyYW0geyEoRWxlbWVudHxOb2RlTGlzdHxzdHJpbmcpfSBjaGlsZCBUaGUgdGhpbmcgdG8gYXBwZW5kIHRvIHRoZSBwYXJlbnQuXG4gKiBAcmV0dXJuIHshRWxlbWVudH0gVGhlIGFwcGVuZGVkIGNoaWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kKHBhcmVudCwgY2hpbGQpIHtcblx0aWYgKGlzU3RyaW5nKGNoaWxkKSkge1xuXHRcdGNoaWxkID0gYnVpbGRGcmFnbWVudChjaGlsZCk7XG5cdH1cblx0aWYgKGlzTm9kZUxpc3RMaWtlKGNoaWxkKSkge1xuXHRcdGNvbnN0IGNoaWxkQXJyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoY2hpbGQpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRBcnIubGVuZ3RoOyBpKyspIHtcblx0XHRcdHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZEFycltpXSk7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG5cdH1cblx0cmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAqIEhlbHBlciBmb3IgY29udmVydGluZyBhIEhUTUwgc3RyaW5nIGludG8gYSBkb2N1bWVudCBmcmFnbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sU3RyaW5nIFRoZSBIVE1MIHN0cmluZyB0byBjb252ZXJ0LlxuICogQHJldHVybiB7IUVsZW1lbnR9IFRoZSByZXN1bHRpbmcgZG9jdW1lbnQgZnJhZ21lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEZyYWdtZW50KGh0bWxTdHJpbmcpIHtcblx0Y29uc3QgdGVtcERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHR0ZW1wRGl2LmlubmVySFRNTCA9IGA8YnI+JHtodG1sU3RyaW5nfWA7XG5cdHRlbXBEaXYucmVtb3ZlQ2hpbGQodGVtcERpdi5maXJzdENoaWxkKTtcblxuXHRjb25zdCBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblx0d2hpbGUgKHRlbXBEaXYuZmlyc3RDaGlsZCkge1xuXHRcdGZyYWdtZW50LmFwcGVuZENoaWxkKHRlbXBEaXYuZmlyc3RDaGlsZCk7XG5cdH1cblx0cmV0dXJuIGZyYWdtZW50O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZmlyc3QgZWxlbWVudCBjb250YWlucyB0aGUgc2Vjb25kIG9uZS5cbiAqIEBkZXByZWNhdGVkIFVzZSBlbGVtZW50MS5jb250YWlucyhlbGVtZW50MikgZGlyZWN0bHkgaW5zdGVhZCBvZiB0aGlzIG1ldGhvZFxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudDFcbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQyXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnMoZWxlbWVudDEsIGVsZW1lbnQyKSB7XG5cdGlmIChpc0RvY3VtZW50KGVsZW1lbnQxKSkge1xuXHRcdC8vIGRvY3VtZW50LmNvbnRhaW5zIGlzIG5vdCBkZWZpbmVkIG9uIElFOSwgc28gY2FsbCBpdCBvbiBkb2N1bWVudEVsZW1lbnQgaW5zdGVhZC5cblx0XHRyZXR1cm4gZWxlbWVudDEuZG9jdW1lbnRFbGVtZW50LmNvbnRhaW5zKGVsZW1lbnQyKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gZWxlbWVudDEuY29udGFpbnMoZWxlbWVudDIpO1xuXHR9XG59XG5cbi8qKlxuICogTGlzdGVucyB0byB0aGUgc3BlY2lmaWVkIGV2ZW50IG9uIHRoZSBnaXZlbiBET00gZWxlbWVudCwgYnV0IG9ubHkgY2FsbHMgdGhlXG4gKiBnaXZlbiBjYWxsYmFjayBsaXN0ZW5lciB3aGVuIGl0J3MgdHJpZ2dlcmVkIGJ5IGVsZW1lbnRzIHRoYXQgbWF0Y2ggdGhlXG4gKiBnaXZlbiBzZWxlY3RvciBvciB0YXJnZXQgZWxlbWVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIERPTSBlbGVtZW50IHRoZSBldmVudCBzaG91bGQgYmUgbGlzdGVuZWQgb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gdG8uXG4gKiBAcGFyYW0geyFFbGVtZW50fHN0cmluZ30gc2VsZWN0b3JPclRhcmdldCBFaXRoZXIgYW4gZWxlbWVudCBvciBjc3Mgc2VsZWN0b3JcbiAqICAgICB0aGF0IHNob3VsZCBtYXRjaCB0aGUgZXZlbnQgZm9yIHRoZSBsaXN0ZW5lciB0byBiZSB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0geyFmdW5jdGlvbighT2JqZWN0KX0gY2FsbGJhY2sgRnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50XG4gKiAgICAgaXMgdHJpZ2dlcmVkLiBJdCB3aWxsIHJlY2VpdmUgdGhlIG5vcm1hbGl6ZWQgZXZlbnQgb2JqZWN0LlxuICogQHBhcmFtIHtib29sZWFuPX0gZGVmYXVsdExpc3RlbmVyIE9wdGlvbmFsIGZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGlzIGEgZGVmYXVsdFxuICogICAgIGxpc3RlbmVyLiBUaGF0IG1lYW5zIHRoYXQgaXQgd291bGQgb25seSBiZSBleGVjdXRlZCBhZnRlciBhbGwgbm9uXG4gKiAgICAgZGVmYXVsdCBsaXN0ZW5lcnMsIGFuZCBvbmx5IGlmIHRoZSBldmVudCBpc24ndCBwcmV2ZW50ZWQgdmlhXG4gKiAgICAgYHByZXZlbnREZWZhdWx0YC5cbiAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGVnYXRlKFxuXHRlbGVtZW50LFxuXHRldmVudE5hbWUsXG5cdHNlbGVjdG9yT3JUYXJnZXQsXG5cdGNhbGxiYWNrLFxuXHRkZWZhdWx0TGlzdGVuZXJcbikge1xuXHRjb25zdCBjdXN0b21Db25maWcgPSBjdXN0b21FdmVudHNbZXZlbnROYW1lXTtcblx0aWYgKGN1c3RvbUNvbmZpZyAmJiBjdXN0b21Db25maWcuZGVsZWdhdGUpIHtcblx0XHRldmVudE5hbWUgPSBjdXN0b21Db25maWcub3JpZ2luYWxFdmVudDtcblx0XHRjYWxsYmFjayA9IGN1c3RvbUNvbmZpZy5oYW5kbGVyLmJpbmQoY3VzdG9tQ29uZmlnLCBjYWxsYmFjayk7XG5cdH1cblxuXHRpZiAoZGVmYXVsdExpc3RlbmVyKSB7XG5cdFx0Ly8gV3JhcCBjYWxsYmFjayBzbyB3ZSBkb24ndCBzZXQgcHJvcGVydHkgZGlyZWN0bHkgb24gaXQuXG5cdFx0Y2FsbGJhY2sgPSBjYWxsYmFjay5iaW5kKCk7XG5cdFx0Y2FsbGJhY2suZGVmYXVsdExpc3RlbmVyXyA9IHRydWU7XG5cdH1cblxuXHRhdHRhY2hEZWxlZ2F0ZUV2ZW50XyhlbGVtZW50LCBldmVudE5hbWUpO1xuXHRpZiAoaXNTdHJpbmcoc2VsZWN0b3JPclRhcmdldCkpIHtcblx0XHRhZGRTZWxlY3Rvckxpc3RlbmVyXyhlbGVtZW50LCBldmVudE5hbWUsIHNlbGVjdG9yT3JUYXJnZXQsIGNhbGxiYWNrKTtcblx0fSBlbHNlIHtcblx0XHRhZGRFbGVtZW50TGlzdGVuZXJfKHNlbGVjdG9yT3JUYXJnZXQsIGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuXHR9XG5cblx0cmV0dXJuIG5ldyBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZShcblx0XHRpc1N0cmluZyhzZWxlY3Rvck9yVGFyZ2V0KSA/IGVsZW1lbnQgOiBzZWxlY3Rvck9yVGFyZ2V0LFxuXHRcdGV2ZW50TmFtZSxcblx0XHRjYWxsYmFjayxcblx0XHRpc1N0cmluZyhzZWxlY3Rvck9yVGFyZ2V0KSA/IHNlbGVjdG9yT3JUYXJnZXQgOiBudWxsXG5cdCk7XG59XG5cbi8qKlxuICogVmVyaWZpZXMgaWYgdGhlIGVsZW1lbnQgaXMgYWJsZSB0byB0cmlnZ2VyIHRoZSBDbGljayBldmVudCxcbiAqIHNpbXVsYXRpbmcgYnJvd3NlcnMgYmVoYXZpb3VyLCBhdm9pZGluZyBldmVudCBsaXN0ZW5lcnMgdG8gYmUgY2FsbGVkIGJ5IHRyaWdnZXJFdmVudCBtZXRob2QuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgRWxlbWVudCB0byBiZSBjaGVja2VkLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZS5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gZXZlbnRPYmpcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc0FibGVUb0ludGVyYWN0V2l0aF8obm9kZSwgZXZlbnROYW1lLCBldmVudE9iaikge1xuXHRpZiAoZXZlbnRPYmogJiYgZXZlbnROYW1lID09PSAnY2xpY2snICYmIGV2ZW50T2JqLmJ1dHRvbiA9PT0gMikge1xuXHRcdC8vIEZpcmVmb3ggdHJpZ2dlcnMgXCJjbGlja1wiIGV2ZW50cyBvbiB0aGUgZG9jdW1lbnQgZm9yIHJpZ2h0IGNsaWNrcy4gVGhpc1xuXHRcdC8vIGNhdXNlcyBvdXIgZGVsZWdhdGUgbG9naWMgdG8gdHJpZ2dlciBpdCBmb3IgcmVndWxhciBlbGVtZW50cyB0b28sIHdoaWNoXG5cdFx0Ly8gc2hvdWxkbid0IGhhcHBlbi4gSWdub3JpbmcgdGhlbSBoZXJlLlxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGNvbnN0IG1hdGNoZXNTZWxlY3RvciA9IFtcblx0XHQnQlVUVE9OJyxcblx0XHQnSU5QVVQnLFxuXHRcdCdTRUxFQ1QnLFxuXHRcdCdURVhUQVJFQScsXG5cdFx0J0ZJRUxEU0VUJyxcblx0XTtcblx0aWYgKGV2ZW50TmFtZSA9PT0gJ2NsaWNrJyAmJiBtYXRjaGVzU2VsZWN0b3IuaW5kZXhPZihub2RlLnRhZ05hbWUpID4gLTEpIHtcblx0XHRyZXR1cm4gIShub2RlLmRpc2FibGVkIHx8IHBhcmVudChub2RlLCAnZmllbGRzZXRbZGlzYWJsZWRdJykpO1xuXHR9XG5cdHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGEgTm9kZUxpc3Qgb3IgbGlrZSBvbmUuXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBsaWtlIGEgTm9kZUxpc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vZGVMaXN0TGlrZSh2YWwpIHtcblx0cmV0dXJuIChcblx0XHRpc0RlZkFuZE5vdE51bGwodmFsKSAmJlxuXHRcdHR5cGVvZiB2YWwubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuXHRcdHR5cGVvZiB2YWwuaXRlbSA9PT0gJ2Z1bmN0aW9uJ1xuXHQpO1xufVxuXG4vKipcbiAqIEluc2VydHMgbm9kZSBpbiBkb2N1bWVudCBhcyBsYXN0IGVsZW1lbnQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgRWxlbWVudCB0byByZW1vdmUgY2hpbGRyZW4gZnJvbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVudGVyRG9jdW1lbnQobm9kZSkge1xuXHRub2RlICYmIGFwcGVuZChkb2N1bWVudC5ib2R5LCBub2RlKTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIG5vZGUgZnJvbSBkb2N1bWVudC5cbiAqIEBwYXJhbSB7RWxlbWVudH0gbm9kZSBFbGVtZW50IHRvIHJlbW92ZSBjaGlsZHJlbiBmcm9tLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXhpdERvY3VtZW50KG5vZGUpIHtcblx0aWYgKG5vZGUgJiYgbm9kZS5wYXJlbnROb2RlKSB7XG5cdFx0bm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpO1xuXHR9XG59XG5cbi8qKlxuICogVGhpcyBpcyBjYWxsZWQgd2hlbiBhbiBldmVudCBpcyB0cmlnZ2VyZWQgYnkgYSBkZWxlZ2F0ZSBsaXN0ZW5lci4gQWxsXG4gKiBtYXRjaGluZyBsaXN0ZW5lcnMgb2YgdGhpcyBldmVudCB0eXBlIGZyb20gYHRhcmdldGAgdG8gYGN1cnJlbnRUYXJnZXRgIHdpbGxcbiAqIGJlIHRyaWdnZXJlZC5cbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBUaGUgZXZlbnQgcGF5bG9hZC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gaGFuZGxlRGVsZWdhdGVFdmVudF8oZXZlbnQpIHtcblx0bm9ybWFsaXplRGVsZWdhdGVFdmVudF8oZXZlbnQpO1xuXHRsZXQgcmV0ID0gdHJ1ZTtcblx0Y29uc3QgY29udGFpbmVyID0gZXZlbnQuY3VycmVudFRhcmdldDtcblx0Y29uc3QgZGVmRm5zID0gW107XG5cblx0cmV0ICY9IHRyaWdnZXJEZWxlZ2F0ZWRMaXN0ZW5lcnNfKGNvbnRhaW5lciwgZXZlbnQsIGRlZkZucyk7XG5cdHJldCAmPSB0cmlnZ2VyRGVmYXVsdERlbGVnYXRlZExpc3RlbmVyc18oZGVmRm5zLCBldmVudCk7XG5cblx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSBudWxsO1xuXHRldmVudFtMQVNUX0NPTlRBSU5FUl0gPSBjb250YWluZXI7XG5cdHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgcmVxdWVzdGVkIGNzcyBjbGFzcy5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNDbGFzcyhlbGVtZW50LCBjbGFzc05hbWUpIHtcblx0aWYgKCdjbGFzc0xpc3QnIGluIGVsZW1lbnQpIHtcblx0XHRyZXR1cm4gaGFzQ2xhc3NXaXRoTmF0aXZlXyhlbGVtZW50LCBjbGFzc05hbWUpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBoYXNDbGFzc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzTmFtZSk7XG5cdH1cbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaGFzIHRoZSByZXF1ZXN0ZWQgY3NzIGNsYXNzIHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBoYXNDbGFzc1dpdGhOYXRpdmVfKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuXHRyZXR1cm4gKFxuXHRcdGNsYXNzTmFtZS5pbmRleE9mKCcgJykgPT09IC0xICYmIGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSlcblx0KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaGFzIHRoZSByZXF1ZXN0ZWQgY3NzIGNsYXNzIHdpdGhvdXQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGhhc0NsYXNzV2l0aG91dE5hdGl2ZV8oZWxlbWVudCwgY2xhc3NOYW1lKSB7XG5cdHJldHVybiAoXG5cdFx0YCAke2VsZW1lbnQuY2xhc3NOYW1lfSBgLmluZGV4T2YoYCAke2NsYXNzTmFtZX0gYCkgPj0gMCAmJlxuXHRcdGNsYXNzTmFtZS5zcGxpdCgnICcpLmxlbmd0aCA9PT0gMVxuXHQpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBpcyBlbXB0eSBvciBub3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShlbGVtZW50KSB7XG5cdHJldHVybiBlbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwO1xufVxuXG4vKipcbiAqIElFMTEgZG9lc24ndCBzdXBwb3J0IEVsZW1lbnQubWF0Y2hlcyBmdW5jdGlvbiwgdGhpcyBtZXRob2RcbiAqIGNoZWNrIGlmIGFuIGVsZW1lbnQgbWF0Y2hlcyBhIGdpdmVuIHNlbGVjdG9yLlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaChlbGVtZW50LCBzZWxlY3Rvcikge1xuXHRpZiAoIWVsZW1lbnQgfHwgZWxlbWVudC5ub2RlVHlwZSAhPT0gMSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGNvbnN0IHAgPSBFbGVtZW50LnByb3RvdHlwZTtcblx0Y29uc3QgbSA9XG5cdFx0cC5tYXRjaGVzIHx8XG5cdFx0cC53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRwLm1vek1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdHAubXNNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRwLm9NYXRjaGVzU2VsZWN0b3I7XG5cdGlmIChtKSB7XG5cdFx0cmV0dXJuIG0uY2FsbChlbGVtZW50LCBzZWxlY3Rvcik7XG5cdH1cblxuXHRyZXR1cm4gbWF0Y2hGYWxsYmFja18oZWxlbWVudCwgc2VsZWN0b3IpO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGFuIGVsZW1lbnQgbWF0Y2hlcyBhIGdpdmVuIHNlbGVjdG9yLCB1c2luZyBhbiBpbnRlcm5hbCBpbXBsZW1lbnRhdGlvblxuICogaW5zdGVhZCBvZiBjYWxsaW5nIGV4aXN0aW5nIGphdmFzY3JpcHQgZnVuY3Rpb25zLlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBtYXRjaEZhbGxiYWNrXyhlbGVtZW50LCBzZWxlY3Rvcikge1xuXHRjb25zdCBwYXJlbnROb2RlID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXG5cdGlmIChwYXJlbnROb2RlKSB7XG5cdFx0Y29uc3Qgbm9kZXMgPSBwYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0aWYgKG5vZGVzW2ldID09PSBlbGVtZW50KSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBuZXh0IHNpYmxpbmcgb2YgdGhlIGdpdmVuIGVsZW1lbnQgdGhhdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWRcbiAqIHNlbGVjdG9yLCBvciBudWxsIGlmIHRoZXJlIGlzIG5vbmUuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0gez9zdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtFbGVtZW50fG51bGx9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuZXh0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XG5cdGRvIHtcblx0XHRlbGVtZW50ID0gZWxlbWVudC5uZXh0U2libGluZztcblx0XHRpZiAoZWxlbWVudCAmJiBtYXRjaChlbGVtZW50LCBzZWxlY3RvcikpIHtcblx0XHRcdHJldHVybiBlbGVtZW50O1xuXHRcdH1cblx0fSB3aGlsZSAoZWxlbWVudCk7XG5cdHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgdGhlIGV2ZW50IHBheWxvYWQgZm9yIGRlbGVnYXRlIGxpc3RlbmVycy5cbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRGVsZWdhdGVFdmVudF8oZXZlbnQpIHtcblx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gc3RvcFByb3BhZ2F0aW9uXztcblx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uXztcbn1cblxuLyoqXG4gKiBMaXN0ZW5zIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQgb24gdGhlIGdpdmVuIERPTSBlbGVtZW50LiBUaGlzIGZ1bmN0aW9uIG5vcm1hbGl6ZXNcbiAqIERPTSBldmVudCBwYXlsb2FkcyBhbmQgZnVuY3Rpb25zIHNvIHRoZXknbGwgd29yayB0aGUgc2FtZSB3YXkgb24gYWxsIHN1cHBvcnRlZFxuICogYnJvd3NlcnMuXG4gKiBAcGFyYW0geyFFbGVtZW50fHN0cmluZ30gZWxlbWVudCBUaGUgRE9NIGVsZW1lbnQgdG8gbGlzdGVuIHRvIHRoZSBldmVudCBvbiwgb3JcbiAqICAgYSBzZWxlY3RvciB0aGF0IHNob3VsZCBiZSBkZWxlZ2F0ZWQgb24gdGhlIGVudGlyZSBkb2N1bWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiB0by5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCFPYmplY3QpfSBjYWxsYmFjayBGdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXNcbiAqICAgdHJpZ2dlcmVkLiBJdCB3aWxsIHJlY2VpdmUgdGhlIG5vcm1hbGl6ZWQgZXZlbnQgb2JqZWN0LlxuICogQHBhcmFtIHtib29sZWFufSBjYXB0dXJlIEZsYWcgaW5kaWNhdGluZyBpZiBsaXN0ZW5lciBzaG91bGQgYmUgdHJpZ2dlcmVkXG4gKiAgIGR1cmluZyBjYXB0dXJlIHBoYXNlLCBpbnN0ZWFkIG9mIGR1cmluZyB0aGUgYnViYmxpbmcgcGhhc2UuIERlZmF1bHRzIHRvIGZhbHNlLlxuICogQHJldHVybiB7IURvbUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb24oZWxlbWVudCwgZXZlbnROYW1lLCBjYWxsYmFjaywgY2FwdHVyZSkge1xuXHRpZiAoaXNTdHJpbmcoZWxlbWVudCkpIHtcblx0XHRyZXR1cm4gZGVsZWdhdGUoZG9jdW1lbnQsIGV2ZW50TmFtZSwgZWxlbWVudCwgY2FsbGJhY2spO1xuXHR9XG5cdGNvbnN0IGN1c3RvbUNvbmZpZyA9IGN1c3RvbUV2ZW50c1tldmVudE5hbWVdO1xuXHRpZiAoY3VzdG9tQ29uZmlnICYmIGN1c3RvbUNvbmZpZy5ldmVudCkge1xuXHRcdGV2ZW50TmFtZSA9IGN1c3RvbUNvbmZpZy5vcmlnaW5hbEV2ZW50O1xuXHRcdGNhbGxiYWNrID0gY3VzdG9tQ29uZmlnLmhhbmRsZXIuYmluZChjdXN0b21Db25maWcsIGNhbGxiYWNrKTtcblx0fVxuXHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBjYWxsYmFjaywgY2FwdHVyZSk7XG5cdHJldHVybiBuZXcgRG9tRXZlbnRIYW5kbGUoZWxlbWVudCwgZXZlbnROYW1lLCBjYWxsYmFjaywgY2FwdHVyZSk7XG59XG5cbi8qKlxuICogSUUxMSBkb2Vzbid0IHN1cHBvcnQgb25jZSBldmVudCBsaXN0ZW5lciBvcHRpb24sIHRoaXMgbWV0aG9kXG4gKiBMaXN0ZW5zIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQgb24gdGhlIGdpdmVuIERPTSBlbGVtZW50IG9uY2UuIFRoaXNcbiAqIGZ1bmN0aW9uIG5vcm1hbGl6ZXMgRE9NIGV2ZW50IHBheWxvYWRzIGFuZCBmdW5jdGlvbnMgc28gdGhleSdsbCB3b3JrIHRoZVxuICogc2FtZSB3YXkgb24gYWxsIHN1cHBvcnRlZCBicm93c2Vycy5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIERPTSBlbGVtZW50IHRvIGxpc3RlbiB0byB0aGUgZXZlbnQgb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gdG8uXG4gKiBAcGFyYW0geyFmdW5jdGlvbighT2JqZWN0KX0gY2FsbGJhY2sgRnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50XG4gKiAgIGlzIHRyaWdnZXJlZC4gSXQgd2lsbCByZWNlaXZlIHRoZSBub3JtYWxpemVkIGV2ZW50IG9iamVjdC5cbiAqIEByZXR1cm4geyFEb21FdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uY2UoZWxlbWVudCwgZXZlbnROYW1lLCBjYWxsYmFjaykge1xuXHRjb25zdCBkb21FdmVudEhhbmRsZSA9IG9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgZnVuY3Rpb24oKSB7XG5cdFx0ZG9tRXZlbnRIYW5kbGUucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHRyZXR1cm4gY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9KTtcblx0cmV0dXJuIGRvbUV2ZW50SGFuZGxlO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIGZpcnN0IHBhcmVudCBmcm9tIHRoZSBnaXZlbiBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkXG4gKiBzZWxlY3Rvciwgb3IgbnVsbCBpZiBub25lIG1hdGNoLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyZW50KGVsZW1lbnQsIHNlbGVjdG9yKSB7XG5cdHJldHVybiBjbG9zZXN0KGVsZW1lbnQucGFyZW50Tm9kZSwgc2VsZWN0b3IpO1xufVxuXG4vKipcbiAqIElFMTEgZG9lc24ndCBzdXBwb3J0IEVsZW1lbnQucHJlcGVuZCBmdW5jdGlvbiwgdGhpcyBtZXRob2RcbiAqIGluc2VydHMgYSBub2RlIGJlZm9yZSBmaXJzdCBjaGlsZCBvZiB0aGUgcGFyZW50LiBJZiBjaGlsZCBpcyBhIEhUTUwgc3RyaW5nXG4gKiBpdCB3aWxsIGJlIGNvbnZlcnRlZCB0byBkb2N1bWVudCBmcmFnbWVudCBiZWZvcmUgcHJlcGVuZGluZyBpdCB0byB0aGUgcGFyZW50LlxuICogQHBhcmFtIHshRWxlbWVudH0gcGFyZW50IFRoZSBub2RlIHRvIHByZXBlbmQgdG8uXG4gKiBAcGFyYW0geyEoRWxlbWVudHxOb2RlTGlzdHxzdHJpbmcpfSBjaGlsZCBUaGUgdGhpbmcgdG8gcHJlcGVuZCB0byB0aGUgcGFyZW50LlxuICogQHJldHVybiB7IUVsZW1lbnR9IFRoZSBwcmVwZW5kZWQgY2hpbGQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVwZW5kKHBhcmVudCwgY2hpbGQpIHtcblx0aWYgKGlzU3RyaW5nKGNoaWxkKSkge1xuXHRcdGNoaWxkID0gYnVpbGRGcmFnbWVudChjaGlsZCk7XG5cdH1cblxuXHRpZiAoIWlzTm9kZUxpc3RMaWtlKGNoaWxkKSAmJiAhaXNEZWZBbmROb3ROdWxsKHBhcmVudC5maXJzdENoaWxkKSkge1xuXHRcdHJldHVybiBhcHBlbmQocGFyZW50LCBjaGlsZCk7XG5cdH1cblxuXHRpZiAoaXNOb2RlTGlzdExpa2UoY2hpbGQpKSB7XG5cdFx0Y29uc3QgY2hpbGRBcnIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChjaGlsZCk7XG5cdFx0Zm9yIChsZXQgaSA9IGNoaWxkQXJyLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0XHRwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkQXJyW2ldLCBwYXJlbnQuZmlyc3RDaGlsZCk7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIHBhcmVudC5maXJzdENoaWxkKTtcblx0fVxuXG5cdHJldHVybiBjaGlsZDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBjdXN0b20gZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBjdXN0b20gZXZlbnQuXG4gKiBAcGFyYW0geyFPYmplY3R9IGN1c3RvbUNvbmZpZyBBbiBvYmplY3Qgd2l0aCBpbmZvcm1hdGlvbiBhYm91dCBob3cgdGhlIGV2ZW50XG4gKiAgIHNob3VsZCBiZSBoYW5kbGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJDdXN0b21FdmVudChldmVudE5hbWUsIGN1c3RvbUNvbmZpZykge1xuXHRjdXN0b21FdmVudHNbZXZlbnROYW1lXSA9IGN1c3RvbUNvbmZpZztcbn1cblxuLyoqXG4gKiBSZW1vdmVzIGFsbCB0aGUgY2hpbGQgbm9kZXMgb24gYSBET00gbm9kZS5cbiAqIEBwYXJhbSB7RWxlbWVudH0gbm9kZSBFbGVtZW50IHRvIHJlbW92ZSBjaGlsZHJlbiBmcm9tLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlQ2hpbGRyZW4obm9kZSkge1xuXHRsZXQgY2hpbGQ7XG5cdHdoaWxlICgoY2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQpKSB7XG5cdFx0bm9kZS5yZW1vdmVDaGlsZChjaGlsZCk7XG5cdH1cbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSByZXF1ZXN0ZWQgQ1NTIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50LlxuICogQHBhcmFtIHshRWxlbWVudHwhTm9kZUxpc3R9IGVsZW1lbnRzIFRoZSBlbGVtZW50IG9yIGVsZW1lbnRzIHRvIHJlbW92ZSBDU1MgY2xhc3NlcyBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gcmVtb3ZlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlQ2xhc3NlcyhlbGVtZW50cywgY2xhc3Nlcykge1xuXHRpZiAoIWlzT2JqZWN0KGVsZW1lbnRzKSB8fCAhaXNTdHJpbmcoY2xhc3NlcykpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuXHRcdGVsZW1lbnRzID0gW2VsZW1lbnRzXTtcblx0fVxuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoJ2NsYXNzTGlzdCcgaW4gZWxlbWVudHNbaV0pIHtcblx0XHRcdHJlbW92ZUNsYXNzZXNXaXRoTmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJlbW92ZUNsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIGZyb20gYW4gZWxlbWVudCB1c2luZyBjbGFzc0xpc3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIHJlbW92ZSBDU1MgY2xhc3NlcyBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gcmVtb3ZlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQ2xhc3Nlc1dpdGhOYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0Y2xhc3Nlcy5zcGxpdCgnICcpLmZvckVhY2goZnVuY3Rpb24oY2xhc3NOYW1lKSB7XG5cdFx0aWYgKGNsYXNzTmFtZSkge1xuXHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSk7XG5cdFx0fVxuXHR9KTtcbn1cblxuLyoqXG4gKiBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBFbGVtZW50LmNsYXNzTGlzdCwgdGhpcyBtZXRob2RcbiAqIHJlbW92ZXMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQgd2l0aG91dCB1c2luZyBjbGFzc0xpc3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIHJlbW92ZSBDU1MgY2xhc3NlcyBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gcmVtb3ZlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0bGV0IGVsZW1lbnRDbGFzc05hbWUgPSBgICR7ZWxlbWVudC5jbGFzc05hbWV9IGA7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRlbGVtZW50Q2xhc3NOYW1lID0gZWxlbWVudENsYXNzTmFtZS5yZXBsYWNlKGAgJHtjbGFzc2VzW2ldfSBgLCAnICcpO1xuXHR9XG5cblx0ZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50Q2xhc3NOYW1lLnRyaW0oKTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlcyB0aGUgZmlyc3QgZWxlbWVudCB3aXRoIHRoZSBzZWNvbmQuXG4gKiBAZGVwcmVjYXRlZCBVc2UgZWxlbWVudDEucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoZWxlbWVudDIsIGVsZW1lbnQxKVxuICogZGlyZWN0bHkgaW5zdGVhZCBvZiB0aGlzIG1ldGhvZFxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50MVxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50MlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZShlbGVtZW50MSwgZWxlbWVudDIpIHtcblx0aWYgKGVsZW1lbnQxICYmIGVsZW1lbnQyICYmIGVsZW1lbnQxICE9PSBlbGVtZW50MiAmJiBlbGVtZW50MS5wYXJlbnROb2RlKSB7XG5cdFx0ZWxlbWVudDEucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoZWxlbWVudDIsIGVsZW1lbnQxKTtcblx0fVxufVxuXG4vKipcbiAqIFRoZSBmdW5jdGlvbiB0aGF0IHJlcGxhY2VzIGBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25fYCBmb3IgZXZlbnRzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uXygpIHtcblx0Y29uc3QgZXZlbnQgPSB0aGlzOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdGV2ZW50LnN0b3BwZWQgPSB0cnVlO1xuXHRldmVudC5zdG9wcGVkSW1tZWRpYXRlID0gdHJ1ZTtcblx0RXZlbnQucHJvdG90eXBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbi5jYWxsKGV2ZW50KTtcbn1cblxuLyoqXG4gKiBUaGUgZnVuY3Rpb24gdGhhdCByZXBsYWNlcyBgc3RvcFByb3BhZ2F0aW9uYCBmb3IgZXZlbnRzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uXygpIHtcblx0Y29uc3QgZXZlbnQgPSB0aGlzOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdGV2ZW50LnN0b3BwZWQgPSB0cnVlO1xuXHRFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uLmNhbGwoZXZlbnQpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBzdXBwb3J0cyB0aGUgZ2l2ZW4gZXZlbnQgdHlwZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR8c3RyaW5nfSBlbGVtZW50IFRoZSBET00gZWxlbWVudCBvciBlbGVtZW50IHRhZyBuYW1lIHRvIGNoZWNrLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gY2hlY2suXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3VwcG9ydHNFdmVudChlbGVtZW50LCBldmVudE5hbWUpIHtcblx0aWYgKGN1c3RvbUV2ZW50c1tldmVudE5hbWVdKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRpZiAoaXNTdHJpbmcoZWxlbWVudCkpIHtcblx0XHRpZiAoIWVsZW1lbnRzQnlUYWdfW2VsZW1lbnRdKSB7XG5cdFx0XHRlbGVtZW50c0J5VGFnX1tlbGVtZW50XSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoZWxlbWVudCk7XG5cdFx0fVxuXHRcdGVsZW1lbnQgPSBlbGVtZW50c0J5VGFnX1tlbGVtZW50XTtcblx0fVxuXG5cdGNvbnN0IHRhZyA9IGVsZW1lbnQudGFnTmFtZTtcblx0aWYgKCFzdXBwb3J0Q2FjaGVfW3RhZ10gfHwgIXN1cHBvcnRDYWNoZV9bdGFnXS5oYXNPd25Qcm9wZXJ0eShldmVudE5hbWUpKSB7XG5cdFx0c3VwcG9ydENhY2hlX1t0YWddID0gc3VwcG9ydENhY2hlX1t0YWddIHx8IHt9O1xuXHRcdHN1cHBvcnRDYWNoZV9bdGFnXVtldmVudE5hbWVdID0gJ29uJyArIGV2ZW50TmFtZSBpbiBlbGVtZW50O1xuXHR9XG5cdHJldHVybiBzdXBwb3J0Q2FjaGVfW3RhZ11bZXZlbnROYW1lXTtcbn1cblxuLyoqXG4gKiBUaGlzIHRyaWdnZXJzIGFsbCBkZWZhdWx0IG1hdGNoZWQgZGVsZWdhdGVkIGxpc3RlbmVycyBvZiBhIGdpdmVuIGV2ZW50IHR5cGUuXG4gKiBAcGFyYW0geyFBcnJheX0gZGVmRm5zIEFycmF5IHRvIGNvbGxlY3QgZGVmYXVsdCBsaXN0ZW5lcnMgaW4sIGluc3RlYWRcbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHJldHVybiB7Ym9vbGVhbn0gRmFsc2UgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSB0cmlnZ2VyZWQgY2FsbGJhY2tzIHJldHVybnNcbiAqICAgICBmYWxzZSwgb3IgdHJ1ZSBvdGhlcndpc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0cmlnZ2VyRGVmYXVsdERlbGVnYXRlZExpc3RlbmVyc18oZGVmRm5zLCBldmVudCkge1xuXHRsZXQgcmV0ID0gdHJ1ZTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGRlZkZucy5sZW5ndGggJiYgIWV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQ7IGkrKykge1xuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gZGVmRm5zW2ldLmVsZW1lbnQ7XG5cdFx0cmV0ICY9IGRlZkZuc1tpXS5mbihldmVudCk7XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFRoaXMgdHJpZ2dlcnMgYWxsIG1hdGNoZWQgZGVsZWdhdGVkIGxpc3RlbmVycyBvZiBhIGdpdmVuIGV2ZW50IHR5cGUgd2hlbiBpdHNcbiAqIGRlbGVnYXRlZCB0YXJnZXQgaXMgYWJsZSB0byBpbnRlcmFjdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGNvbnRhaW5lclxuICogQHBhcmFtIHshRXZlbnR9IGV2ZW50XG4gKiBAcGFyYW0geyFBcnJheX0gZGVmYXVsdEZucyBBcnJheSB0byBjb2xsZWN0IGRlZmF1bHQgbGlzdGVuZXJzIGluLCBpbnN0ZWFkXG4gKiAgICAgb2YgcnVubmluZyB0aGVtLlxuICogQHJldHVybiB7Ym9vbGVhbn0gRmFsc2UgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSB0cmlnZ2VyZWQgY2FsbGJhY2tzIHJldHVybnNcbiAqICAgICBmYWxzZSwgb3IgdHJ1ZSBvdGhlcndpc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0cmlnZ2VyRGVsZWdhdGVkTGlzdGVuZXJzXyhjb250YWluZXIsIGV2ZW50LCBkZWZhdWx0Rm5zKSB7XG5cdGxldCByZXQgPSB0cnVlO1xuXHRsZXQgY3VyckVsZW1lbnQgPSBldmVudC50YXJnZXQ7XG5cdGNvbnN0IGxpbWl0ID0gY29udGFpbmVyLnBhcmVudE5vZGU7XG5cblx0d2hpbGUgKGN1cnJFbGVtZW50ICYmIGN1cnJFbGVtZW50ICE9PSBsaW1pdCAmJiAhZXZlbnQuc3RvcHBlZCkge1xuXHRcdGlmIChpc0FibGVUb0ludGVyYWN0V2l0aF8oY3VyckVsZW1lbnQsIGV2ZW50LnR5cGUsIGV2ZW50KSkge1xuXHRcdFx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSBjdXJyRWxlbWVudDtcblx0XHRcdHJldCAmPSB0cmlnZ2VyRWxlbWVudExpc3RlbmVyc18oY3VyckVsZW1lbnQsIGV2ZW50LCBkZWZhdWx0Rm5zKTtcblx0XHRcdHJldCAmPSB0cmlnZ2VyU2VsZWN0b3JMaXN0ZW5lcnNfKFxuXHRcdFx0XHRjb250YWluZXIsXG5cdFx0XHRcdGN1cnJFbGVtZW50LFxuXHRcdFx0XHRldmVudCxcblx0XHRcdFx0ZGVmYXVsdEZuc1xuXHRcdFx0KTtcblx0XHR9XG5cdFx0Y3VyckVsZW1lbnQgPSBjdXJyRWxlbWVudC5wYXJlbnROb2RlO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gYXJndW1lbnQgdG8gYSBET00gZWxlbWVudC4gU3RyaW5ncyBhcmUgYXNzdW1lZCB0b1xuICogYmUgc2VsZWN0b3JzLCBhbmQgc28gYSBtYXRjaGVkIGVsZW1lbnQgd2lsbCBiZSByZXR1cm5lZC4gSWYgdGhlIGFyZ1xuICogaXMgYWxyZWFkeSBhIERPTSBlbGVtZW50IGl0IHdpbGwgYmUgdGhlIHJldHVybiB2YWx1ZS5cbiAqIEBwYXJhbSB7c3RyaW5nfEVsZW1lbnR8RG9jdW1lbnR9IHNlbGVjdG9yT3JFbGVtZW50XG4gKiBAcmV0dXJuIHtFbGVtZW50fSBUaGUgY29udmVydGVkIGVsZW1lbnQsIG9yIG51bGwgaWYgbm9uZSB3YXMgZm91bmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0VsZW1lbnQoc2VsZWN0b3JPckVsZW1lbnQpIHtcblx0aWYgKFxuXHRcdGlzRWxlbWVudChzZWxlY3Rvck9yRWxlbWVudCkgfHxcblx0XHRpc0RvY3VtZW50KHNlbGVjdG9yT3JFbGVtZW50KSB8fFxuXHRcdGlzRG9jdW1lbnRGcmFnbWVudChzZWxlY3Rvck9yRWxlbWVudClcblx0KSB7XG5cdFx0cmV0dXJuIHNlbGVjdG9yT3JFbGVtZW50O1xuXHR9IGVsc2UgaWYgKGlzU3RyaW5nKHNlbGVjdG9yT3JFbGVtZW50KSkge1xuXHRcdHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yT3JFbGVtZW50KTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxufVxuXG4vKipcbiAqIEFkZHMgb3IgcmVtb3ZlcyBvbmUgb3IgbW9yZSBjbGFzc2VzIGZyb20gYW4gZWxlbWVudC4gSWYgYW55IG9mIHRoZSBjbGFzc2VzXG4gKiBpcyBwcmVzZW50LCBpdCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudCwgb3IgYWRkZWQgb3RoZXJ3aXNlLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB3aGljaCBjbGFzc2VzIHdpbGwgYmUgdG9nZ2xlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc2VzIFRoZSBjbGFzc2VzIHdoaWNoIGhhdmUgdG8gYWRkZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBlbGVtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlQ2xhc3NlcyhlbGVtZW50LCBjbGFzc2VzKSB7XG5cdGlmICghaXNPYmplY3QoZWxlbWVudCkgfHwgIWlzU3RyaW5nKGNsYXNzZXMpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKCdjbGFzc0xpc3QnIGluIGVsZW1lbnQpIHtcblx0XHR0b2dnbGVDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcyk7XG5cdH0gZWxzZSB7XG5cdFx0dG9nZ2xlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpO1xuXHR9XG59XG5cbi8qKlxuICogQWRkcyBvciByZW1vdmVzIG9uZSBvciBtb3JlIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50IHVzaW5nIGNsYXNzTGlzdC5cbiAqIElmIGFueSBvZiB0aGUgY2xhc3NlcyBpcyBwcmVzZW50LCBpdCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudCxcbiAqIG9yIGFkZGVkIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgd2hpY2ggY2xhc3NlcyB3aWxsIGJlIHRvZ2dsZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBUaGUgY2xhc3NlcyB3aGljaCBoYXZlIHRvIGFkZGVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRvZ2dsZUNsYXNzZXNXaXRoTmF0aXZlXyhlbGVtZW50LCBjbGFzc2VzKSB7XG5cdGNsYXNzZXMuc3BsaXQoJyAnKS5mb3JFYWNoKGZ1bmN0aW9uKGNsYXNzTmFtZSkge1xuXHRcdGVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZShjbGFzc05hbWUpO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBFbGVtZW50LmNsYXNzTGlzdCwgdGhpcyBtZXRob2RcbiAqIGFkZHMgb3IgcmVtb3ZlcyBvbmUgb3IgbW9yZSBjbGFzc2VzIGZyb20gYW4gZWxlbWVudCB3aXRob3V0IHVzaW5nIGNsYXNzTGlzdC5cbiAqIElmIGFueSBvZiB0aGUgY2xhc3NlcyBpcyBwcmVzZW50LCBpdCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudCxcbiAqIG9yIGFkZGVkIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgd2hpY2ggY2xhc3NlcyB3aWxsIGJlIHRvZ2dsZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBUaGUgY2xhc3NlcyB3aGljaCBoYXZlIHRvIGFkZGVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRvZ2dsZUNsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc2VzKSB7XG5cdGxldCBlbGVtZW50Q2xhc3NOYW1lID0gYCAke2VsZW1lbnQuY2xhc3NOYW1lfSBgO1xuXG5cdGNsYXNzZXMgPSBjbGFzc2VzLnNwbGl0KCcgJyk7XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjbGFzc2VzLmxlbmd0aDsgaSsrKSB7XG5cdFx0Y29uc3QgY2xhc3NOYW1lID0gYCAke2NsYXNzZXNbaV19IGA7XG5cdFx0Y29uc3QgY2xhc3NJbmRleCA9IGVsZW1lbnRDbGFzc05hbWUuaW5kZXhPZihjbGFzc05hbWUpO1xuXG5cdFx0aWYgKGNsYXNzSW5kZXggPT09IC0xKSB7XG5cdFx0XHRlbGVtZW50Q2xhc3NOYW1lID0gYCR7ZWxlbWVudENsYXNzTmFtZX0ke2NsYXNzZXNbaV19IGA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IGJlZm9yZSA9IGVsZW1lbnRDbGFzc05hbWUuc3Vic3RyaW5nKDAsIGNsYXNzSW5kZXgpO1xuXHRcdFx0Y29uc3QgYWZ0ZXIgPSBlbGVtZW50Q2xhc3NOYW1lLnN1YnN0cmluZyhcblx0XHRcdFx0Y2xhc3NJbmRleCArIGNsYXNzTmFtZS5sZW5ndGhcblx0XHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdGVsZW1lbnRDbGFzc05hbWUgPSBgJHtiZWZvcmV9ICR7YWZ0ZXJ9YDtcblx0XHR9XG5cdH1cblxuXHRlbGVtZW50LmNsYXNzTmFtZSA9IGVsZW1lbnRDbGFzc05hbWUudHJpbSgpO1xufVxuXG4vKipcbiAqIFRyaWdnZXJzIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBnaXZlbiBldmVudCB0eXBlIHRoYXQgYXJlIHN0b3JlZCBpbiB0aGVcbiAqIHNwZWNpZmllZCBlbGVtZW50LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHshRXZlbnR9IGV2ZW50XG4gKiBAcGFyYW0geyFBcnJheX0gZGVmYXVsdEZucyBBcnJheSB0byBjb2xsZWN0IGRlZmF1bHQgbGlzdGVuZXJzIGluLCBpbnN0ZWFkXG4gKiAgICAgb2YgcnVubmluZyB0aGVtLlxuICogQHJldHVybiB7Ym9vbGVhbn0gRmFsc2UgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSB0cmlnZ2VyZWQgY2FsbGJhY2tzIHJldHVybnNcbiAqICAgICBmYWxzZSwgb3IgdHJ1ZSBvdGhlcndpc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0cmlnZ2VyRWxlbWVudExpc3RlbmVyc18oZWxlbWVudCwgZXZlbnQsIGRlZmF1bHRGbnMpIHtcblx0Y29uc3QgbGFzdENvbnRhaW5lciA9IGV2ZW50W0xBU1RfQ09OVEFJTkVSXTtcblx0aWYgKCFpc0RlZihsYXN0Q29udGFpbmVyKSB8fCAhY29udGFpbnMobGFzdENvbnRhaW5lciwgZWxlbWVudCkpIHtcblx0XHRjb25zdCBsaXN0ZW5lcnMgPSBkb21EYXRhLmdldChlbGVtZW50LCAnbGlzdGVuZXJzJywge30pW2V2ZW50LnR5cGVdO1xuXHRcdHJldHVybiB0cmlnZ2VyTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGV2ZW50LCBlbGVtZW50LCBkZWZhdWx0Rm5zKTtcblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBUcmlnZ2VycyB0aGUgc3BlY2lmaWVkIGV2ZW50IG9uIHRoZSBnaXZlbiBlbGVtZW50LlxuICogTk9URTogVGhpcyBzaG91bGQgbW9zdGx5IGJlIHVzZWQgZm9yIHRlc3RpbmcsIG5vdCBvbiByZWFsIGNvZGUuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBub2RlIHRoYXQgc2hvdWxkIHRyaWdnZXIgdGhlIGV2ZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gYmUgdHJpZ2dyZWQuXG4gKiBAcGFyYW0ge09iamVjdD19IGV2ZW50T2JqIEFuIG9iamVjdCB3aXRoIGRhdGEgdGhhdCBzaG91bGQgYmUgb24gdGhlXG4gKiAgIHRyaWdnZXJlZCBldmVudCdzIHBheWxvYWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmlnZ2VyRXZlbnQoZWxlbWVudCwgZXZlbnROYW1lLCBldmVudE9iaikge1xuXHRpZiAoaXNBYmxlVG9JbnRlcmFjdFdpdGhfKGVsZW1lbnQsIGV2ZW50TmFtZSwgZXZlbnRPYmopKSB7XG5cdFx0Y29uc3QgcGF5bG9hZCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJyk7XG5cdFx0cGF5bG9hZC5pbml0RXZlbnQoZXZlbnROYW1lLCB0cnVlLCB0cnVlKTtcblx0XHRvYmplY3QubWl4aW4ocGF5bG9hZCwgZXZlbnRPYmopO1xuXHRcdGVsZW1lbnQuZGlzcGF0Y2hFdmVudChwYXlsb2FkKTtcblx0fVxufVxuXG4vKipcbiAqIFRyaWdnZXJzIHRoZSBnaXZlbiBsaXN0ZW5lcnMgYXJyYXkuXG4gKiBAcGFyYW0ge0FycmF5PCFmdW5jdGlvbigpPn0gbGlzdGVuZXJzXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZhdWx0Rm5zIEFycmF5IHRvIGNvbGxlY3QgZGVmYXVsdCBsaXN0ZW5lcnMgaW4sIGluc3RlYWRcbiAqICAgICBvZiBydW5uaW5nIHRoZW0uXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJMaXN0ZW5lcnNfKGxpc3RlbmVycywgZXZlbnQsIGVsZW1lbnQsIGRlZmF1bHRGbnMpIHtcblx0bGV0IHJldCA9IHRydWU7XG5cdGxpc3RlbmVycyA9IGxpc3RlbmVycyB8fCBbXTtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoICYmICFldmVudC5zdG9wcGVkSW1tZWRpYXRlOyBpKyspIHtcblx0XHRpZiAobGlzdGVuZXJzW2ldLmRlZmF1bHRMaXN0ZW5lcl8pIHtcblx0XHRcdGRlZmF1bHRGbnMucHVzaCh7XG5cdFx0XHRcdGVsZW1lbnQsXG5cdFx0XHRcdGZuOiBsaXN0ZW5lcnNbaV0sXG5cdFx0XHR9KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0ICY9IGxpc3RlbmVyc1tpXShldmVudCk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogVHJpZ2dlcnMgYWxsIHNlbGVjdG9yIGxpc3RlbmVycyBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHshRWxlbWVudH0gY29udGFpbmVyXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZhdWx0Rm5zIEFycmF5IHRvIGNvbGxlY3QgZGVmYXVsdCBsaXN0ZW5lcnMgaW4sIGluc3RlYWRcbiAqICAgICBvZiBydW5uaW5nIHRoZW0uXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJTZWxlY3Rvckxpc3RlbmVyc18oY29udGFpbmVyLCBlbGVtZW50LCBldmVudCwgZGVmYXVsdEZucykge1xuXHRsZXQgcmV0ID0gdHJ1ZTtcblx0Y29uc3QgZGF0YSA9IGRvbURhdGEuZ2V0KGNvbnRhaW5lciwgJ2RlbGVnYXRpbmcnLCB7fSk7XG5cdGNvbnN0IG1hcCA9IGRhdGFbZXZlbnQudHlwZV0uc2VsZWN0b3JzO1xuXHRjb25zdCBzZWxlY3RvcnMgPSBPYmplY3Qua2V5cyhtYXApO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IHNlbGVjdG9ycy5sZW5ndGggJiYgIWV2ZW50LnN0b3BwZWRJbW1lZGlhdGU7IGkrKykge1xuXHRcdGlmIChtYXRjaChlbGVtZW50LCBzZWxlY3RvcnNbaV0pKSB7XG5cdFx0XHRjb25zdCBsaXN0ZW5lcnMgPSBtYXBbc2VsZWN0b3JzW2ldXTtcblx0XHRcdHJldCAmPSB0cmlnZ2VyTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGV2ZW50LCBlbGVtZW50LCBkZWZhdWx0Rm5zKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHJldDtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gVGhpcyBmaWxlIGV4aXN0cyBqdXN0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgbWFraW5nIHN1cmUgdGhhdCBvbGRcbi8vIGRlZmF1bHQgaW1wb3J0cyBmb3IgdGhpcyBmaWxlIHN0aWxsIHdvcmsuIEl0J3MgYmVzdCB0byB1c2UgdGhlIG5hbWVkIGV4cG9ydHNcbi8vIGZvciBlYWNoIGZ1bmN0aW9uIGluc3RlYWQgdGhvdWdoLCBzaW5jZSB0aGF0IGFsbG93cyBidW5kbGVycyBsaWtlIFJvbGx1cCB0b1xuLy8gcmVkdWNlIHRoZSBidW5kbGUgc2l6ZSBieSByZW1vdmluZyB1bnVzZWQgY29kZS5cbmltcG9ydCAqIGFzIGRvbSBmcm9tICcuL2RvbU5hbWVkJztcblxuZXhwb3J0IGRlZmF1bHQgZG9tO1xuZXhwb3J0IHtkb219O1xuZXhwb3J0ICogZnJvbSAnLi9kb21OYW1lZCc7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7ZGVsZWdhdGUsIG9uLCBzdXBwb3J0c0V2ZW50fSBmcm9tICcuL2RvbSc7XG5pbXBvcnQge0V2ZW50RW1pdHRlclByb3h5fSBmcm9tICdtZXRhbC1ldmVudHMnO1xuXG4vKipcbiAqIERvbUV2ZW50RW1pdHRlclByb3h5IHV0aWxpdHkuIEl0IGV4dGVuZHMgYEV2ZW50RW1pdHRlclByb3h5YCB0byBhbHNvIGFjY2VwdFxuICogZG9tIGVsZW1lbnRzIGFzIG9yaWdpbiBlbWl0dGVycy5cbiAqIEBleHRlbmRzIHtFdmVudEVtaXR0ZXJQcm94eX1cbiAqL1xuY2xhc3MgRG9tRXZlbnRFbWl0dGVyUHJveHkgZXh0ZW5kcyBFdmVudEVtaXR0ZXJQcm94eSB7XG5cdC8qKlxuXHQgKiBBZGRzIHRoZSBnaXZlbiBsaXN0ZW5lciBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBUaGUgbGlzdGVuZWQgZXZlbnQncyBoYW5kbGUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRhZGRMaXN0ZW5lcl8oZXZlbnQsIGxpc3RlbmVyKSB7XG5cdFx0aWYgKHRoaXMub3JpZ2luRW1pdHRlcl8uYWRkRXZlbnRMaXN0ZW5lcikge1xuXHRcdFx0aWYgKHRoaXMuaXNEZWxlZ2F0ZUV2ZW50XyhldmVudCkpIHtcblx0XHRcdFx0Y29uc3QgaW5kZXggPSBldmVudC5pbmRleE9mKCc6JywgOSk7XG5cdFx0XHRcdGNvbnN0IGV2ZW50TmFtZSA9IGV2ZW50LnN1YnN0cmluZyg5LCBpbmRleCk7XG5cdFx0XHRcdGNvbnN0IHNlbGVjdG9yID0gZXZlbnQuc3Vic3RyaW5nKGluZGV4ICsgMSk7XG5cdFx0XHRcdHJldHVybiBkZWxlZ2F0ZShcblx0XHRcdFx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfLFxuXHRcdFx0XHRcdGV2ZW50TmFtZSxcblx0XHRcdFx0XHRzZWxlY3Rvcixcblx0XHRcdFx0XHRsaXN0ZW5lclxuXHRcdFx0XHQpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gb24odGhpcy5vcmlnaW5FbWl0dGVyXywgZXZlbnQsIGxpc3RlbmVyKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHN1cGVyLmFkZExpc3RlbmVyXyhldmVudCwgbGlzdGVuZXIpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGV2ZW50IGlzIG9mIHRoZSBkZWxlZ2F0ZSB0eXBlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0aXNEZWxlZ2F0ZUV2ZW50XyhldmVudCkge1xuXHRcdHJldHVybiBldmVudC5zdWJzdHIoMCwgOSkgPT09ICdkZWxlZ2F0ZTonO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXZlbnQgaXMgc3VwcG9ydGVkIGJ5IHRoZSBvcmlnaW4gZWxlbWVudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzU3VwcG9ydGVkRG9tRXZlbnRfKGV2ZW50KSB7XG5cdFx0aWYgKCF0aGlzLm9yaWdpbkVtaXR0ZXJfIHx8ICF0aGlzLm9yaWdpbkVtaXR0ZXJfLmFkZEV2ZW50TGlzdGVuZXIpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gKFxuXHRcdFx0KHRoaXMuaXNEZWxlZ2F0ZUV2ZW50XyhldmVudCkgJiYgZXZlbnQuaW5kZXhPZignOicsIDkpICE9PSAtMSkgfHxcblx0XHRcdHN1cHBvcnRzRXZlbnQodGhpcy5vcmlnaW5FbWl0dGVyXywgZXZlbnQpXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGV2ZW50IHNob3VsZCBiZSBwcm94aWVkLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByb3RlY3RlZFxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdHNob3VsZFByb3h5RXZlbnRfKGV2ZW50KSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdHN1cGVyLnNob3VsZFByb3h5RXZlbnRfKGV2ZW50KSAmJiB0aGlzLmlzU3VwcG9ydGVkRG9tRXZlbnRfKGV2ZW50KVxuXHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBEb21FdmVudEVtaXR0ZXJQcm94eTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcHBlbmR9IGZyb20gJy4vZG9tJztcbmltcG9ydCB7c3RyaW5nfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogQ2xhc3Mgd2l0aCBzdGF0aWMgbWV0aG9kcyByZXNwb25zaWJsZSBmb3IgZG9pbmcgYnJvd3NlciBmZWF0dXJlIGNoZWNrcy5cbiAqL1xuY2xhc3MgZmVhdHVyZXMge1xuXHQvKipcblx0ICogU29tZSBicm93c2VycyBzdGlsbCBzdXBwb3J0cyBwcmVmaXhlZCBhbmltYXRpb24gZXZlbnRzLiBUaGlzIG1ldGhvZCBjYW5cblx0ICogYmUgdXNlZCB0byByZXRyaWV2ZSB0aGUgY3VycmVudCBicm93c2VyIGV2ZW50IG5hbWUgZm9yIGJvdGgsIGFuaW1hdGlvblxuXHQgKiBhbmQgdHJhbnNpdGlvbi5cblx0ICogQHJldHVybiB7b2JqZWN0fVxuXHQgKi9cblx0c3RhdGljIGNoZWNrQW5pbWF0aW9uRXZlbnROYW1lKCkge1xuXHRcdGlmIChmZWF0dXJlcy5hbmltYXRpb25FdmVudE5hbWVfID09PSB1bmRlZmluZWQpIHtcblx0XHRcdGZlYXR1cmVzLmFuaW1hdGlvbkV2ZW50TmFtZV8gPSB7XG5cdFx0XHRcdGFuaW1hdGlvbjogZmVhdHVyZXMuY2hlY2tBbmltYXRpb25FdmVudE5hbWVfKCdhbmltYXRpb24nKSxcblx0XHRcdFx0dHJhbnNpdGlvbjogZmVhdHVyZXMuY2hlY2tBbmltYXRpb25FdmVudE5hbWVfKCd0cmFuc2l0aW9uJyksXG5cdFx0XHR9O1xuXHRcdH1cblx0XHRyZXR1cm4gZmVhdHVyZXMuYW5pbWF0aW9uRXZlbnROYW1lXztcblx0fVxuXG5cdC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFR5cGUgdG8gdGVzdDogYW5pbWF0aW9uLCB0cmFuc2l0aW9uLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEJyb3dzZXIgZXZlbnQgbmFtZS5cblx0ICovXG5cdHN0YXRpYyBjaGVja0FuaW1hdGlvbkV2ZW50TmFtZV8odHlwZSkge1xuXHRcdGNvbnN0IHByZWZpeGVzID0gWydXZWJraXQnLCAnTVMnLCAnTycsICcnXTtcblx0XHRjb25zdCB0eXBlVGl0bGVDYXNlID0gc3RyaW5nLnJlcGxhY2VJbnRlcnZhbChcblx0XHRcdHR5cGUsXG5cdFx0XHQwLFxuXHRcdFx0MSxcblx0XHRcdHR5cGUuc3Vic3RyaW5nKDAsIDEpLnRvVXBwZXJDYXNlKClcblx0XHQpO1xuXHRcdGNvbnN0IHN1ZmZpeGVzID0gW1xuXHRcdFx0YCR7dHlwZVRpdGxlQ2FzZX1FbmRgLFxuXHRcdFx0YCR7dHlwZVRpdGxlQ2FzZX1FbmRgLFxuXHRcdFx0YCR7dHlwZVRpdGxlQ2FzZX1FbmRgLFxuXHRcdFx0YCR7dHlwZX1lbmRgLFxuXHRcdF07XG5cdFx0aWYgKCFmZWF0dXJlcy5hbmltYXRpb25FbGVtZW50Xykge1xuXHRcdFx0ZmVhdHVyZXMuYW5pbWF0aW9uRWxlbWVudF8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHR9XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBwcmVmaXhlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKFxuXHRcdFx0XHRmZWF0dXJlcy5hbmltYXRpb25FbGVtZW50Xy5zdHlsZVtcblx0XHRcdFx0XHRwcmVmaXhlc1tpXSArIHR5cGVUaXRsZUNhc2Vcblx0XHRcdFx0XSAhPT0gdW5kZWZpbmVkIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdCkge1xuXHRcdFx0XHRyZXR1cm4gcHJlZml4ZXNbaV0udG9Mb3dlckNhc2UoKSArIHN1ZmZpeGVzW2ldO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gYCR7dHlwZX1lbmRgO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNvbWUgYnJvd3NlcnMgKGxpa2UgSUUxMSwgRWRnZSkgY2hhbmdlIHRoZSBvcmRlciBvZiBlbGVtZW50IGF0dHJpYnV0ZXMsIHdoZW4gaHRtbFxuXHQgKiBpcyByZW5kZXJlZC4gVGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgdGhpcyBiZWhhdmlvciBoYXBwZW5zIG9uXG5cdCAqIHRoZSBjdXJyZW50IGJyb3dzZXIuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRzdGF0aWMgY2hlY2tBdHRyT3JkZXJDaGFuZ2UoKSB7XG5cdFx0aWYgKGZlYXR1cmVzLmF0dHJPcmRlckNoYW5nZV8gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0Y29uc3Qgb3JpZ2luYWxDb250ZW50ID0gJzxkaXYgZGF0YS1jb21wb25lbnQ9XCJcIiBkYXRhLXJlZj1cIlwiPjwvZGl2Pic7XG5cdFx0XHRjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0XHRhcHBlbmQoZWxlbWVudCwgb3JpZ2luYWxDb250ZW50KTtcblx0XHRcdGZlYXR1cmVzLmF0dHJPcmRlckNoYW5nZV8gPSBvcmlnaW5hbENvbnRlbnQgIT09IGVsZW1lbnQuaW5uZXJIVE1MO1xuXHRcdH1cblx0XHRyZXR1cm4gZmVhdHVyZXMuYXR0ck9yZGVyQ2hhbmdlXztcblx0fVxufVxuXG5mZWF0dXJlcy5hbmltYXRpb25FbGVtZW50XyA9IHVuZGVmaW5lZDtcbmZlYXR1cmVzLmFuaW1hdGlvbkV2ZW50TmFtZV8gPSB1bmRlZmluZWQ7XG5mZWF0dXJlcy5hdHRyT3JkZXJDaGFuZ2VfID0gdW5kZWZpbmVkO1xuXG5leHBvcnQgZGVmYXVsdCBmZWF0dXJlcztcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthc3luY30gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHtleGl0RG9jdW1lbnQsIG9uY2V9IGZyb20gJy4vZG9tJztcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgcnVubmluZyBqYXZhc2NyaXB0IGNvZGUgaW4gdGhlIGdsb2JhbCBzY29wZS5cbiAqL1xuY2xhc3MgZ2xvYmFsRXZhbCB7XG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdGhlIGdpdmVuIHN0cmluZyBpbiB0aGUgZ2xvYmFsIHNjb3BlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzY3JpcHRcblx0ICovXG5cdHN0YXRpYyBydW4odGV4dCwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRzY3JpcHQudGV4dCA9IHRleHQ7XG5cdFx0aWYgKGFwcGVuZEZuKSB7XG5cdFx0XHRhcHBlbmRGbihzY3JpcHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG5cdFx0fVxuXHRcdGV4aXREb2N1bWVudChzY3JpcHQpO1xuXHRcdHJldHVybiBzY3JpcHQ7XG5cdH1cblxuXHQvKipcblx0ICogRXZhbHVhdGVzIHRoZSBnaXZlbiBqYXZhc2NyaXB0IGZpbGUgaW4gdGhlIGdsb2JhbCBzY29wZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHNyYyBUaGUgZmlsZSdzIHBhdGguXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWRcblx0ICogICB3aGVuIHRoZSBzY3JpcHQgaGFzIGJlZW4gcnVuLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzY3JpcHRcblx0ICovXG5cdHN0YXRpYyBydW5GaWxlKHNyYywgZGVmYXVsdEZuLCBhcHBlbmRGbikge1xuXHRcdGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXHRcdHNjcmlwdC5zcmMgPSBzcmM7XG5cblx0XHRjb25zdCBjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0ZXhpdERvY3VtZW50KHNjcmlwdCk7XG5cdFx0XHRkZWZhdWx0Rm4gJiYgZGVmYXVsdEZuKCk7XG5cdFx0fTtcblx0XHRvbmNlKHNjcmlwdCwgJ2xvYWQnLCBjYWxsYmFjayk7XG5cdFx0b25jZShzY3JpcHQsICdlcnJvcicsIGNhbGxiYWNrKTtcblxuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc2NyaXB0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH1cblxuXHRcdHJldHVybiBzY3JpcHQ7XG5cdH1cblxuXHQvKipcblx0ICogRXZhbHVhdGVzIHRoZSBjb2RlIHJlZmVyZW5jZWQgYnkgdGhlIGdpdmVuIHNjcmlwdCBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBzY3JpcHRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiAgIHdoZW4gdGhlIHNjcmlwdCBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9IHNjcmlwdFxuXHQgKi9cblx0c3RhdGljIHJ1blNjcmlwdChzY3JpcHQsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGVmYXVsdEZuICYmIGRlZmF1bHRGbigpO1xuXHRcdH07XG5cdFx0aWYgKHNjcmlwdC50eXBlICYmIHNjcmlwdC50eXBlICE9PSAndGV4dC9qYXZhc2NyaXB0Jykge1xuXHRcdFx0YXN5bmMubmV4dFRpY2soY2FsbGJhY2spO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRleGl0RG9jdW1lbnQoc2NyaXB0KTtcblx0XHRpZiAoc2NyaXB0LnNyYykge1xuXHRcdFx0cmV0dXJuIGdsb2JhbEV2YWwucnVuRmlsZShzY3JpcHQuc3JjLCBkZWZhdWx0Rm4sIGFwcGVuZEZuKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YXN5bmMubmV4dFRpY2soY2FsbGJhY2spO1xuXHRcdFx0cmV0dXJuIGdsb2JhbEV2YWwucnVuKHNjcmlwdC50ZXh0LCBhcHBlbmRGbik7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyBhbnkgc2NyaXB0IHRhZ3MgcHJlc2VudCBpbiB0aGUgZ2l2ZW4gZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICovXG5cdHN0YXRpYyBydW5TY3JpcHRzSW5FbGVtZW50KGVsZW1lbnQsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBzY3JpcHRzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzY3JpcHQnKTtcblx0XHRpZiAoc2NyaXB0cy5sZW5ndGgpIHtcblx0XHRcdGdsb2JhbEV2YWwucnVuU2NyaXB0c0luT3JkZXIoc2NyaXB0cywgMCwgZGVmYXVsdEZuLCBhcHBlbmRGbik7XG5cdFx0fSBlbHNlIGlmIChkZWZhdWx0Rm4pIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGRlZmF1bHRGbik7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGdpdmVuIHNjcmlwdHMgZWxlbWVudHMgaW4gdGhlIG9yZGVyIHRoYXQgdGhleSBhcHBlYXIuXG5cdCAqIEBwYXJhbSB7IU5vZGVMaXN0fSBzY3JpcHRzXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICovXG5cdHN0YXRpYyBydW5TY3JpcHRzSW5PcmRlcihzY3JpcHRzLCBpbmRleCwgZGVmYXVsdEZuLCBhcHBlbmRGbikge1xuXHRcdGdsb2JhbEV2YWwucnVuU2NyaXB0KFxuXHRcdFx0c2NyaXB0cy5pdGVtKGluZGV4KSxcblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoaW5kZXggPCBzY3JpcHRzLmxlbmd0aCAtIDEpIHtcblx0XHRcdFx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdHNJbk9yZGVyKFxuXHRcdFx0XHRcdFx0c2NyaXB0cyxcblx0XHRcdFx0XHRcdGluZGV4ICsgMSxcblx0XHRcdFx0XHRcdGRlZmF1bHRGbixcblx0XHRcdFx0XHRcdGFwcGVuZEZuXG5cdFx0XHRcdFx0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdFx0XHR9IGVsc2UgaWYgKGRlZmF1bHRGbikge1xuXHRcdFx0XHRcdGFzeW5jLm5leHRUaWNrKGRlZmF1bHRGbik7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRhcHBlbmRGblxuXHRcdCk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZ2xvYmFsRXZhbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthc3luY30gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHtvbmNlfSBmcm9tICcuL2RvbSc7XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIHJ1bm5pbmcgc3R5bGVzLlxuICovXG5jbGFzcyBnbG9iYWxFdmFsU3R5bGVzIHtcblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gc3R5bGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9IHN0eWxlXG5cdCAqL1xuXHRzdGF0aWMgcnVuKHRleHQsIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuXHRcdHN0eWxlLmlubmVySFRNTCA9IHRleHQ7XG5cdFx0aWYgKGFwcGVuZEZuKSB7XG5cdFx0XHRhcHBlbmRGbihzdHlsZSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuXHRcdH1cblx0XHRyZXR1cm4gc3R5bGU7XG5cdH1cblxuXHQvKipcblx0ICogRXZhbHVhdGVzIHRoZSBnaXZlbiBzdHlsZSBmaWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaHJlZiBUaGUgZmlsZSdzIHBhdGguXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWRcblx0ICogICB3aGVuIHRoZSBzdHlsZXMgaGFzIGJlZW4gcnVuLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzdHlsZVxuXHQgKi9cblx0c3RhdGljIHJ1bkZpbGUoaHJlZiwgZGVmYXVsdEZuLCBhcHBlbmRGbikge1xuXHRcdGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaW5rJyk7XG5cdFx0bGluay5yZWwgPSAnc3R5bGVzaGVldCc7XG5cdFx0bGluay5ocmVmID0gaHJlZjtcblx0XHRnbG9iYWxFdmFsU3R5bGVzLnJ1blN0eWxlKGxpbmssIGRlZmF1bHRGbiwgYXBwZW5kRm4pO1xuXHRcdHJldHVybiBsaW5rO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgY29kZSByZWZlcmVuY2VkIGJ5IHRoZSBnaXZlbiBzdHlsZS9saW5rIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IHN0eWxlXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWRcblx0ICogICB3aGVuIHRoZSBzY3JpcHQgaGFzIGJlZW4gcnVuLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiAgQHJldHVybiB7RWxlbWVudH0gc3R5bGVcblx0ICovXG5cdHN0YXRpYyBydW5TdHlsZShzdHlsZSwgZGVmYXVsdEZuLCBhcHBlbmRGbikge1xuXHRcdGNvbnN0IGNhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRkZWZhdWx0Rm4gJiYgZGVmYXVsdEZuKCk7XG5cdFx0fTtcblx0XHRpZiAoXG5cdFx0XHRzdHlsZS5yZWwgJiZcblx0XHRcdHN0eWxlLnJlbCAhPT0gJ3N0eWxlc2hlZXQnICYmXG5cdFx0XHRzdHlsZS5yZWwgIT09ICdjYW5vbmljYWwnICYmXG5cdFx0XHRzdHlsZS5yZWwgIT09ICdhbHRlcm5hdGUnXG5cdFx0KSB7XG5cdFx0XHRhc3luYy5uZXh0VGljayhjYWxsYmFjayk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKFxuXHRcdFx0c3R5bGUudGFnTmFtZSA9PT0gJ1NUWUxFJyB8fFxuXHRcdFx0c3R5bGUucmVsID09PSAnY2Fub25pY2FsJyB8fFxuXHRcdFx0c3R5bGUucmVsID09PSAnYWx0ZXJuYXRlJ1xuXHRcdCkge1xuXHRcdFx0YXN5bmMubmV4dFRpY2soY2FsbGJhY2spO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvbmNlKHN0eWxlLCAnbG9hZCcsIGNhbGxiYWNrKTtcblx0XHRcdG9uY2Uoc3R5bGUsICdlcnJvcicsIGNhbGxiYWNrKTtcblx0XHR9XG5cblx0XHRpZiAoYXBwZW5kRm4pIHtcblx0XHRcdGFwcGVuZEZuKHN0eWxlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHN0eWxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyBhbnkgc3R5bGUgcHJlc2VudCBpbiB0aGUgZ2l2ZW4gZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlXG5cdCAqICAgc3R5bGUgaGFzIGJlZW4gcnVuLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKi9cblx0c3RhdGljIHJ1blN0eWxlc0luRWxlbWVudChlbGVtZW50LCBkZWZhdWx0Rm4sIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc3R5bGVzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzdHlsZSxsaW5rJyk7XG5cdFx0aWYgKHN0eWxlcy5sZW5ndGggPT09IDAgJiYgZGVmYXVsdEZuKSB7XG5cdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxldCBsb2FkQ291bnQgPSAwO1xuXHRcdGNvbnN0IGNhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoZGVmYXVsdEZuICYmICsrbG9hZENvdW50ID09PSBzdHlsZXMubGVuZ3RoKSB7XG5cdFx0XHRcdGFzeW5jLm5leHRUaWNrKGRlZmF1bHRGbik7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Z2xvYmFsRXZhbFN0eWxlcy5ydW5TdHlsZShzdHlsZXNbaV0sIGNhbGxiYWNrLCBhcHBlbmRGbik7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGdsb2JhbEV2YWxTdHlsZXM7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7aXNTZXJ2ZXJTaWRlfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQge3JlZ2lzdGVyQ3VzdG9tRXZlbnQsIGNvbnRhaW5zfSBmcm9tICcuL2RvbSc7XG5pbXBvcnQgZmVhdHVyZXMgZnJvbSAnLi9mZWF0dXJlcyc7XG5cbi8qKlxuICogUmVnaXN0ZXIgY3VzdG9tIGV2ZW50cyBmb3IgZXZlbnQgZGVsZWdhdGlvbi5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMoKSB7XG5cdGNvbnN0IG1vdXNlRXZlbnRNYXAgPSB7XG5cdFx0bW91c2VlbnRlcjogJ21vdXNlb3ZlcicsXG5cdFx0bW91c2VsZWF2ZTogJ21vdXNlb3V0Jyxcblx0XHRwb2ludGVyZW50ZXI6ICdwb2ludGVyb3ZlcicsXG5cdFx0cG9pbnRlcmxlYXZlOiAncG9pbnRlcm91dCcsXG5cdH07XG5cdE9iamVjdC5rZXlzKG1vdXNlRXZlbnRNYXApLmZvckVhY2goZnVuY3Rpb24oZXZlbnROYW1lKSB7XG5cdFx0cmVnaXN0ZXJDdXN0b21FdmVudChldmVudE5hbWUsIHtcblx0XHRcdGRlbGVnYXRlOiB0cnVlLFxuXHRcdFx0aGFuZGxlcjogZnVuY3Rpb24oY2FsbGJhY2ssIGV2ZW50KSB7XG5cdFx0XHRcdGNvbnN0IHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0O1xuXHRcdFx0XHRjb25zdCB0YXJnZXQgPSBldmVudC5kZWxlZ2F0ZVRhcmdldDtcblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHQhcmVsYXRlZCB8fFxuXHRcdFx0XHRcdChyZWxhdGVkICE9PSB0YXJnZXQgJiYgIWNvbnRhaW5zKHRhcmdldCwgcmVsYXRlZCkpXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdGV2ZW50LmN1c3RvbVR5cGUgPSBldmVudE5hbWU7XG5cdFx0XHRcdFx0cmV0dXJuIGNhbGxiYWNrKGV2ZW50KTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdG9yaWdpbmFsRXZlbnQ6IG1vdXNlRXZlbnRNYXBbZXZlbnROYW1lXSxcblx0XHR9KTtcblx0fSk7XG5cblx0Y29uc3QgYW5pbWF0aW9uRXZlbnRNYXAgPSB7XG5cdFx0YW5pbWF0aW9uOiAnYW5pbWF0aW9uZW5kJyxcblx0XHR0cmFuc2l0aW9uOiAndHJhbnNpdGlvbmVuZCcsXG5cdH07XG5cdE9iamVjdC5rZXlzKGFuaW1hdGlvbkV2ZW50TWFwKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50VHlwZSkge1xuXHRcdGNvbnN0IGV2ZW50TmFtZSA9IGFuaW1hdGlvbkV2ZW50TWFwW2V2ZW50VHlwZV07XG5cdFx0cmVnaXN0ZXJDdXN0b21FdmVudChldmVudE5hbWUsIHtcblx0XHRcdGV2ZW50OiB0cnVlLFxuXHRcdFx0ZGVsZWdhdGU6IHRydWUsXG5cdFx0XHRoYW5kbGVyOiBmdW5jdGlvbihjYWxsYmFjaywgZXZlbnQpIHtcblx0XHRcdFx0ZXZlbnQuY3VzdG9tVHlwZSA9IGV2ZW50TmFtZTtcblx0XHRcdFx0cmV0dXJuIGNhbGxiYWNrKGV2ZW50KTtcblx0XHRcdH0sXG5cdFx0XHRvcmlnaW5hbEV2ZW50OiBmZWF0dXJlcy5jaGVja0FuaW1hdGlvbkV2ZW50TmFtZSgpW2V2ZW50VHlwZV0sXG5cdFx0fSk7XG5cdH0pO1xufVxuXG5pZiAoIWlzU2VydmVyU2lkZSgpKSB7XG5cdHJlZ2lzdGVyRXZlbnRzKCk7XG59XG4iLCJ2YXIgZ2xvYmFscyA9IGdsb2JhbHMgfHwge307XG5cbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuXHRnbG9iYWxzLndpbmRvdyA9IHdpbmRvdztcbn1cblxuaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0Z2xvYmFscy5kb2N1bWVudCA9IGRvY3VtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBnbG9iYWxzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBjb3JlIHV0aWxpdHkgZnVuY3Rpb25zLlxuICogQGNvbnN0XG4gKi9cblxubGV0IGNvbXBhdGliaWxpdHlNb2RlRGF0YV87XG5cbi8qKlxuICogQ291bnRlciBmb3IgdW5pcXVlIGlkLlxuICogQHR5cGUge051bWJlcn1cbiAqIEBwcml2YXRlXG4gKi9cbmxldCB1bmlxdWVJZENvdW50ZXJfID0gMTtcblxuLyoqXG4gKiBVbmlxdWUgaWQgcHJvcGVydHkgcHJlZml4LlxuICogQHR5cGUge1N0cmluZ31cbiAqIEBwcm90ZWN0ZWRcbiAqL1xuZXhwb3J0IGNvbnN0IFVJRF9QUk9QRVJUWSA9IGBjb3JlXyR7KE1hdGgucmFuZG9tKCkgKiAxZTkpID4+PiAwfWA7XG5cbi8qKlxuICogV2hlbiBkZWZpbmluZyBhIGNsYXNzIEZvbyB3aXRoIGFuIGFic3RyYWN0IG1ldGhvZCBiYXIoKSwgeW91IGNhbiBkbzpcbiAqIEZvby5wcm90b3R5cGUuYmFyID0gYWJzdHJhY3RNZXRob2RcbiAqXG4gKiBOb3cgaWYgYSBzdWJjbGFzcyBvZiBGb28gZmFpbHMgdG8gb3ZlcnJpZGUgYmFyKCksIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duXG4gKiB3aGVuIGJhcigpIGlzIGludm9rZWQuXG4gKlxuICogQHR5cGUgeyFGdW5jdGlvbn1cbiAqIEB0aHJvd3Mge0Vycm9yfSB3aGVuIGludm9rZWQgdG8gaW5kaWNhdGUgdGhlIG1ldGhvZCBzaG91bGQgYmUgb3ZlcnJpZGRlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFic3RyYWN0TWV0aG9kKCkge1xuXHR0aHJvdyBFcnJvcignVW5pbXBsZW1lbnRlZCBhYnN0cmFjdCBtZXRob2QnKTtcbn1cblxuLyoqXG4gKiBEaXNhYmxlcyBNZXRhbC5qcydzIGNvbXBhdGliaWxpdHkgbW9kZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2FibGVDb21wYXRpYmlsaXR5TW9kZSgpIHtcblx0Y29tcGF0aWJpbGl0eU1vZGVEYXRhXyA9IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBFbmFibGVzIE1ldGFsLmpzJ3MgY29tcGF0aWJpbGl0eSBtb2RlIHdpdGggdGhlIGZvbGxvd2luZyBmZWF0dXJlcyBmcm9tIHJjXG4gKiBhbmQgMS54IHZlcnNpb25zOlxuICogICAgIC0gVXNpbmcgXCJrZXlcIiB0byByZWZlcmVuY2UgY29tcG9uZW50IGluc3RhbmNlcy4gSW4gdGhlIGN1cnJlbnQgdmVyc2lvblxuICogICAgICAgdGhpcyBzaG91bGQgYmUgZG9uZSB2aWEgXCJyZWZcIiBpbnN0ZWFkLiBUaGlzIGFsbG93cyBvbGQgY29kZSBzdGlsbFxuICogICAgICAgdXNpbmcgXCJrZXlcIiB0byBrZWVwIHdvcmtpbmcgbGlrZSBiZWZvcmUuIE5PVEU6IHRoaXMgbWF5IGNhdXNlXG4gKiAgICAgICBwcm9ibGVtcywgc2luY2UgXCJrZXlcIiBpcyBtZWFudCB0byBiZSB1c2VkIGRpZmZlcmVudGx5LiBPbmx5IHVzZSB0aGlzXG4gKiAgICAgICBpZiBpdCdzIG5vdCBwb3NzaWJsZSB0byB1cGdyYWRlIHRoZSBjb2RlIHRvIHVzZSBcInJlZlwiIGluc3RlYWQuXG4gKiBAcGFyYW0ge09iamVjdD19IGRhdGEgT3B0aW9uYWwgb2JqZWN0IHdpdGggZGF0YSB0byBzcGVjaWZ5IG1vcmVcbiAqICAgICBkZXRhaWxzLCBzdWNoIGFzOlxuICogICAgICAgICAtIHJlbmRlcmVycyB7QXJyYXl9IHRoZSB0ZW1wbGF0ZSByZW5kZXJlcnMgdGhhdCBzaG91bGQgYmUgaW5cbiAqICAgICAgICAgICBjb21wYXRpYmlsaXR5IG1vZGUsIGVpdGhlciB0aGVpciBjb25zdHJ1Y3RvcnMgb3Igc3RyaW5nc1xuICogICAgICAgICAgIHJlcHJlc2VudGluZyB0aGVtIChlLmcuICdzb3knIG9yICdqc3gnKS4gQnkgZGVmYXVsdCwgYWxsIHRoZSBvbmVzXG4gKiAgICAgICAgICAgdGhhdCBleHRlbmQgZnJvbSBJbmNyZW1lbnRhbERvbVJlbmRlcmVyLlxuICogQHR5cGUge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuYWJsZUNvbXBhdGliaWxpdHlNb2RlKGRhdGEgPSB7fSkge1xuXHRjb21wYXRpYmlsaXR5TW9kZURhdGFfID0gZGF0YTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBkYXRhIHVzZWQgZm9yIGNvbXBhdGliaWxpdHkgbW9kZSwgb3Igbm90aGluZyBpZiBpdCBoYXNuJ3QgYmVlblxuICogZW5hYmxlZC5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvbXBhdGliaWxpdHlNb2RlRGF0YSgpIHtcblx0Ly8gQ29tcGF0aWJpbGl0eSBtb2RlIGNhbiBiZSBzZXQgdmlhIHRoZSBfX01FVEFMX0NPTVBBVElCSUxJVFlfXyBnbG9iYWwgdmFyLlxuXHRpZiAoY29tcGF0aWJpbGl0eU1vZGVEYXRhXyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5fX01FVEFMX0NPTVBBVElCSUxJVFlfXykge1xuXHRcdFx0ZW5hYmxlQ29tcGF0aWJpbGl0eU1vZGUod2luZG93Ll9fTUVUQUxfQ09NUEFUSUJJTElUWV9fKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGNvbXBhdGliaWxpdHlNb2RlRGF0YV87XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgaWYgaXQncyB0cnV0aHksIG9yIHRoZSBzZWNvbmQgb3RoZXJ3aXNlLlxuICogQHBhcmFtIHsqfSBhXG4gKiBAcGFyYW0geyp9IGJcbiAqIEByZXR1cm4geyp9XG4gKiBAcHJvdGVjdGVkXG4gKi9cbmZ1bmN0aW9uIGdldEZpcnN0VHJ1dGh5XyhhLCBiKSB7XG5cdHJldHVybiBhIHx8IGI7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgZ2l2ZW4gZnVuY3Rpb24uIElmIHRoZSBjdXJyZW50IGJyb3dzZXIgZG9lc24ndFxuICogc3VwcG9ydCB0aGUgYG5hbWVgIHByb3BlcnR5LCB0aGlzIHdpbGwgY2FsY3VsYXRlIGl0IGZyb20gdGhlIGZ1bmN0aW9uJ3NcbiAqIGNvbnRlbnQgc3RyaW5nLlxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gZm5cbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uTmFtZShmbikge1xuXHRpZiAoIWZuLm5hbWUpIHtcblx0XHRjb25zdCBzdHIgPSBmbi50b1N0cmluZygpO1xuXHRcdGZuLm5hbWUgPSBzdHIuc3Vic3RyaW5nKDksIHN0ci5pbmRleE9mKCcoJykpO1xuXHR9XG5cdHJldHVybiBmbi5uYW1lO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgc3RhdGljIHByb3BlcnR5IGluIHRoZSBnaXZlbiBjbGFzcy4gVGhlIHZhbHVlIHdpbGwgYmVcbiAqIGluaGVyaXRlZCBmcm9tIGFuY2VzdG9ycyBhcyBleHBlY3RlZCwgdW5sZXNzIGEgY3VzdG9tIG1lcmdlIGZ1bmN0aW9uIGlzIGdpdmVuLFxuICogd2hpY2ggY2FuIGNoYW5nZSBob3cgdGhlIHN1cGVyIGNsYXNzZXMnIHZhbHVlIGZvciB0aGF0IHByb3BlcnR5IHdpbGwgYmUgbWVyZ2VkXG4gKiB0b2dldGhlci5cbiAqIFRoZSBmaW5hbCBtZXJnZWQgdmFsdWUgd2lsbCBiZSBzdG9yZWQgaW4gYW5vdGhlciBwcm9wZXJ0eSwgc28gdGhhdCBpdCB3b24ndFxuICogYmUgcmVjYWxjdWxhdGVkIGV2ZW4gaWYgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgbXVsdGlwbGUgdGltZXMuXG4gKiBAcGFyYW0geyFmdW5jdGlvbigpfSBjdG9yIENsYXNzIGNvbnN0cnVjdG9yLlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5TmFtZSBQcm9wZXJ0eSBuYW1lIHRvIGJlIG1lcmdlZC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKiwgKik6Kj19IG1lcmdlRm4gRnVuY3Rpb24gdGhhdCByZWNlaXZlcyB0aGUgbWVyZ2VkXG4gKiAgICAgdmFsdWUgb2YgdGhlIHByb3BlcnR5IHNvIGZhciBhbmQgdGhlIG5leHQgdmFsdWUgdG8gYmUgbWVyZ2VkIHRvIGl0LlxuICogICAgIFNob3VsZCByZXR1cm4gdGhlc2UgdHdvIG1lcmdlZCB0b2dldGhlci4gSWYgbm90IHBhc3NlZCB0aGUgZmluYWwgcHJvcGVydHlcbiAqICAgICB3aWxsIGJlIHRoZSBmaXJzdCB0cnV0aHkgdmFsdWUgYW1vbmcgYW5jZXN0b3JzLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RhdGljUHJvcGVydHkoXG5cdGN0b3IsXG5cdHByb3BlcnR5TmFtZSxcblx0bWVyZ2VGbiA9IGdldEZpcnN0VHJ1dGh5X1xuKSB7XG5cdGNvbnN0IG1lcmdlZE5hbWUgPSBwcm9wZXJ0eU5hbWUgKyAnX01FUkdFRCc7XG5cdGlmICghY3Rvci5oYXNPd25Qcm9wZXJ0eShtZXJnZWROYW1lKSkge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXHRcdGxldCBtZXJnZWQgPSBjdG9yLmhhc093blByb3BlcnR5KHByb3BlcnR5TmFtZSlcblx0XHRcdD8gY3Rvcltwcm9wZXJ0eU5hbWVdXG5cdFx0XHQ6IG51bGw7XG5cdFx0aWYgKGN0b3IuX19wcm90b19fICYmICFjdG9yLl9fcHJvdG9fXy5pc1Byb3RvdHlwZU9mKEZ1bmN0aW9uKSkge1xuXHRcdFx0bWVyZ2VkID0gbWVyZ2VGbihcblx0XHRcdFx0bWVyZ2VkLFxuXHRcdFx0XHRnZXRTdGF0aWNQcm9wZXJ0eShjdG9yLl9fcHJvdG9fXywgcHJvcGVydHlOYW1lLCBtZXJnZUZuKVxuXHRcdFx0KTtcblx0XHR9XG5cdFx0Y3RvclttZXJnZWROYW1lXSA9IG1lcmdlZDtcblx0fVxuXHRyZXR1cm4gY3RvclttZXJnZWROYW1lXTtcbn1cblxuLyoqXG4gKiBHZXRzIGFuIHVuaXF1ZSBpZC4gSWYgYG9iamVjdGAgYXJndW1lbnQgaXMgcGFzc2VkLCB0aGUgb2JqZWN0IGlzXG4gKiBtdXRhdGVkIHdpdGggYW4gdW5pcXVlIGlkLiBDb25zZWN1dGl2ZSBjYWxscyB3aXRoIHRoZSBzYW1lIG9iamVjdFxuICogcmVmZXJlbmNlIHdvbid0IG11dGF0ZSB0aGUgb2JqZWN0IGFnYWluLCBpbnN0ZWFkIHRoZSBjdXJyZW50IG9iamVjdCB1aWRcbiAqIHJldHVybnMuIFNlZSB7QGxpbmsgVUlEX1BST1BFUlRZfS5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gb2JqZWN0IE9wdGlvbmFsIG9iamVjdCB0byBiZSBtdXRhdGVkIHdpdGggdGhlIHVpZC4gSWZcbiAqICAgICBub3Qgc3BlY2lmaWVkIHRoaXMgbWV0aG9kIG9ubHkgcmV0dXJucyB0aGUgdWlkLlxuICogQHBhcmFtIHtib29sZWFuPX0gbm9Jbmhlcml0YW5jZSBPcHRpb25hbCBmbGFnIGluZGljYXRpbmcgaWYgdGhpc1xuICogICAgIG9iamVjdCdzIHVpZCBwcm9wZXJ0eSBjYW4gYmUgaW5oZXJpdGVkIGZyb20gcGFyZW50cyBvciBub3QuXG4gKiBAdGhyb3dzIHtFcnJvcn0gd2hlbiBpbnZva2VkIHRvIGluZGljYXRlIHRoZSBtZXRob2Qgc2hvdWxkIGJlIG92ZXJyaWRkZW4uXG4gKiBAcmV0dXJuIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRVaWQob2JqZWN0LCBub0luaGVyaXRhbmNlKSB7XG5cdGlmIChvYmplY3QpIHtcblx0XHRsZXQgaWQgPSBvYmplY3RbVUlEX1BST1BFUlRZXTtcblx0XHRpZiAobm9Jbmhlcml0YW5jZSAmJiAhb2JqZWN0Lmhhc093blByb3BlcnR5KFVJRF9QUk9QRVJUWSkpIHtcblx0XHRcdGlkID0gbnVsbDtcblx0XHR9XG5cdFx0cmV0dXJuIGlkIHx8IChvYmplY3RbVUlEX1BST1BFUlRZXSA9IHVuaXF1ZUlkQ291bnRlcl8rKyk7XG5cdH1cblx0cmV0dXJuIHVuaXF1ZUlkQ291bnRlcl8rKztcbn1cblxuLyoqXG4gKiBUaGUgaWRlbnRpdHkgZnVuY3Rpb24uIFJldHVybnMgaXRzIGZpcnN0IGFyZ3VtZW50LlxuICogQHBhcmFtIHsqPX0gcmV0dXJuVmFsdWUgVGhlIHNpbmdsZSB2YWx1ZSB0aGF0IHdpbGwgYmUgcmV0dXJuZWQuXG4gKiBAcmV0dXJuIHs/fSBUaGUgZmlyc3QgYXJndW1lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpZGVudGl0eUZ1bmN0aW9uKHJldHVyblZhbHVlKSB7XG5cdHJldHVybiByZXR1cm5WYWx1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIGJvb2xlYW4uXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBib29sZWFuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCb29sZWFuKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ2Jvb2xlYW4nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIG5vdCB1bmRlZmluZWQuXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBkZWZpbmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEZWYodmFsKSB7XG5cdHJldHVybiB2YWwgIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgbm90IHVuZGVmaW5lZCBvciBudWxsLlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZkFuZE5vdE51bGwodmFsKSB7XG5cdHJldHVybiBpc0RlZih2YWwpICYmICFpc051bGwodmFsKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBkb2N1bWVudC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEb2N1bWVudCh2YWwpIHtcblx0cmV0dXJuIHZhbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiB2YWwubm9kZVR5cGUgPT09IDk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgZG9jdW1lbnQtZnJhZ21lbnQuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRG9jdW1lbnRGcmFnbWVudCh2YWwpIHtcblx0cmV0dXJuIHZhbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiB2YWwubm9kZVR5cGUgPT09IDExO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIGRvbSBlbGVtZW50LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0VsZW1lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSAxO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGEgZnVuY3Rpb24uXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBhIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNGdW5jdGlvbih2YWwpIHtcblx0cmV0dXJuIHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIG51bGwuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTnVsbCh2YWwpIHtcblx0cmV0dXJuIHZhbCA9PT0gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGEgbnVtYmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXIodmFsKSB7XG5cdHJldHVybiB0eXBlb2YgdmFsID09PSAnbnVtYmVyJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSB3aW5kb3cuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzV2luZG93KHZhbCkge1xuXHRyZXR1cm4gdmFsICE9PSBudWxsICYmIHZhbCA9PT0gdmFsLndpbmRvdztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhbiBvYmplY3QuIFRoaXMgaW5jbHVkZXMgYXJyYXlzXG4gKiBhbmQgZnVuY3Rpb25zLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYW4gb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPYmplY3QodmFsKSB7XG5cdGNvbnN0IHR5cGUgPSB0eXBlb2YgdmFsO1xuXHRyZXR1cm4gKHR5cGUgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbCkgfHwgdHlwZSA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBQcm9taXNlLlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Byb21pc2UodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbC50aGVuID09PSAnZnVuY3Rpb24nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIHN0cmluZy5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcodmFsKSB7XG5cdHJldHVybiB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyB8fCB2YWwgaW5zdGFuY2VvZiBTdHJpbmc7XG59XG5cbi8qKlxuICogU2V0cyB0byB0cnVlIGlmIHJ1bm5pbmcgaW5zaWRlIE5vZGUuanMgZW52aXJvbm1lbnQgd2l0aCBleHRyYSBjaGVjayBmb3JcbiAqIGBwcm9jZXNzLmJyb3dzZXJgIHRvIHNraXAgS2FybWEgcnVubmVyIGVudmlyb25tZW50LiBLYXJtYSBlbnZpcm9ubWVudCBoYXNcbiAqIGBwcm9jZXNzYCBkZWZpbmVkIGV2ZW4gdGhvdWdoIGl0IHJ1bnMgb24gdGhlIGJyb3dzZXIuXG4gKiBAcGFyYW0gez9PYmplY3R9IG9wdGlvbnMgQ29udGFpbnMgYGNoZWNrRW52YCBwcm9wZXJ0eSB3aGljaCBpZiB0cnVlLCBjaGVja3NcbiAqIHRoZSBOT0RFX0VOViB2YXJpYWJsZS4gSWYgTk9ERV9FTlYgZXF1YWxzICd0ZXN0JywgdGhlIGZ1bmN0aW9uIHJldHVybnMgZmFsc2UuXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTZXJ2ZXJTaWRlKG9wdGlvbnMgPSB7Y2hlY2tFbnY6IHRydWV9KSB7XG5cdGxldCBzZXJ2ZXJTaWRlID0gdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmICFwcm9jZXNzLmJyb3dzZXI7XG5cdGlmIChzZXJ2ZXJTaWRlICYmIG9wdGlvbnMuY2hlY2tFbnYpIHtcblx0XHRzZXJ2ZXJTaWRlID1cblx0XHRcdHR5cGVvZiBwcm9jZXNzLmVudiAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHRcdHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCc7XG5cdH1cblx0cmV0dXJuIHNlcnZlclNpZGU7XG59XG5cbi8qKlxuICogTnVsbCBmdW5jdGlvbiB1c2VkIGZvciBkZWZhdWx0IHZhbHVlcyBvZiBjYWxsYmFja3MsIGV0Yy5cbiAqIEByZXR1cm4ge3ZvaWR9IE5vdGhpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBudWxsRnVuY3Rpb24oKSB7fVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBUaGlzIGZpbGUgZXhpc3RzIGp1c3QgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBtYWtpbmcgc3VyZSB0aGF0IG9sZFxuLy8gZGVmYXVsdCBpbXBvcnRzIGZvciB0aGlzIGZpbGUgc3RpbGwgd29yay4gSXQncyBiZXN0IHRvIHVzZSB0aGUgbmFtZWQgZXhwb3J0c1xuLy8gZm9yIGVhY2ggZnVuY3Rpb24gaW5zdGVhZCB0aG91Z2gsIHNpbmNlIHRoYXQgYWxsb3dzIGJ1bmRsZXJzIGxpa2UgUm9sbHVwIHRvXG4vLyByZWR1Y2UgdGhlIGJ1bmRsZSBzaXplIGJ5IHJlbW92aW5nIHVudXNlZCBjb2RlLlxuaW1wb3J0ICogYXMgY29yZSBmcm9tICcuL2NvcmVOYW1lZCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNvcmU7XG5leHBvcnQge2NvcmV9O1xuZXhwb3J0ICogZnJvbSAnLi9jb3JlTmFtZWQnO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFNldCBvZiB1dGlsaXRpZXMgZm9yIGFycmF5IG9wZXJhdGlvbnNcbiAqL1xuY2xhc3MgYXJyYXkge1xuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBhcnJheXMgaGF2ZSB0aGUgc2FtZSBjb250ZW50LlxuXHQgKiBAcGFyYW0geyFBcnJheTwqPn0gYXJyMVxuXHQgKiBAcGFyYW0geyFBcnJheTwqPn0gYXJyMlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGVxdWFsKGFycjEsIGFycjIpIHtcblx0XHRpZiAoYXJyMSA9PT0gYXJyMikge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdGlmIChhcnIxLmxlbmd0aCAhPT0gYXJyMi5sZW5ndGgpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnIxLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoYXJyMVtpXSAhPT0gYXJyMltpXSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBnaXZlbiBhcnJheSB0aGF0IGlzbid0IHVuZGVmaW5lZC5cblx0ICogQHBhcmFtIHshQXJyYXl9IGFyclxuXHQgKiBAcmV0dXJuIHsqfVxuXHQgKi9cblx0c3RhdGljIGZpcnN0RGVmaW5lZFZhbHVlKGFycikge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoYXJyW2ldICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmV0dXJuIGFycltpXTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVHJhbnNmb3JtcyB0aGUgaW5wdXQgbmVzdGVkIGFycmF5IHRvIGJlY29tZSBmbGF0LlxuXHQgKiBAcGFyYW0ge0FycmF5LjwqfEFycmF5LjwqPj59IGFyciBOZXN0ZWQgYXJyYXkgdG8gZmxhdHRlbi5cblx0ICogQHBhcmFtIHtBcnJheS48Kj49fSBvdXRwdXQgT3B0aW9uYWwgb3V0cHV0IGFycmF5LlxuXHQgKiBAcmV0dXJuIHtBcnJheS48Kj59IEZsYXQgYXJyYXkuXG5cdCAqL1xuXHRzdGF0aWMgZmxhdHRlbihhcnIsIG91dHB1dCA9IFtdKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChBcnJheS5pc0FycmF5KGFycltpXSkpIHtcblx0XHRcdFx0YXJyYXkuZmxhdHRlbihhcnJbaV0sIG91dHB1dCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvdXRwdXQucHVzaChhcnJbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYSBwYXJ0aWN1bGFyIHZhbHVlIGZyb20gYW4gYXJyYXkuXG5cdCAqIEBwYXJhbSB7QXJyYXkuPFQ+fSBhcnIgQXJyYXkgZnJvbSB3aGljaCB0byByZW1vdmUgdmFsdWUuXG5cdCAqIEBwYXJhbSB7VH0gb2JqIE9iamVjdCB0byByZW1vdmUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgYW4gZWxlbWVudCB3YXMgcmVtb3ZlZC5cblx0ICogQHRlbXBsYXRlIFRcblx0ICovXG5cdHN0YXRpYyByZW1vdmUoYXJyLCBvYmopIHtcblx0XHRjb25zdCBpID0gYXJyLmluZGV4T2Yob2JqKTtcblx0XHRsZXQgcnY7XG5cdFx0aWYgKChydiA9IGkgPj0gMCkpIHtcblx0XHRcdGFycmF5LnJlbW92ZUF0KGFyciwgaSk7XG5cdFx0fVxuXHRcdHJldHVybiBydjtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGZyb20gYW4gYXJyYXkgdGhlIGVsZW1lbnQgYXQgaW5kZXggaVxuXHQgKiBAcGFyYW0ge0FycmF5fSBhcnIgQXJyYXkgb3IgYXJyYXkgbGlrZSBvYmplY3QgZnJvbSB3aGljaCB0byByZW1vdmUgdmFsdWUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBpIFRoZSBpbmRleCB0byByZW1vdmUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgYW4gZWxlbWVudCB3YXMgcmVtb3ZlZC5cblx0ICovXG5cdHN0YXRpYyByZW1vdmVBdChhcnIsIGkpIHtcblx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNwbGljZS5jYWxsKGFyciwgaSwgMSkubGVuZ3RoID09PSAxO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNsaWNlcyB0aGUgZ2l2ZW4gYXJyYXksIGp1c3QgbGlrZSBBcnJheS5wcm90b3R5cGUuc2xpY2UsIGJ1dCB0aGlzXG5cdCAqIGlzIGZhc3RlciBhbmQgd29ya2luZyBvbiBhbGwgYXJyYXktbGlrZSBvYmplY3RzIChsaWtlIGFyZ3VtZW50cykuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gYXJyIEFycmF5LWxpa2Ugb2JqZWN0IHRvIHNsaWNlLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIGluZGV4IHRoYXQgc2hvdWxkIHN0YXJ0IHRoZSBzbGljZS5cblx0ICogQHBhcmFtIHtudW1iZXI9fSBlbmQgVGhlIGluZGV4IHdoZXJlIHRoZSBzbGljZSBzaG91bGQgZW5kLCBub3Rcblx0ICogICBpbmNsdWRlZCBpbiB0aGUgZmluYWwgYXJyYXkuIElmIG5vdCBnaXZlbiwgYWxsIGVsZW1lbnRzIGFmdGVyIHRoZVxuXHQgKiAgIHN0YXJ0IGluZGV4IHdpbGwgYmUgaW5jbHVkZWQuXG5cdCAqIEByZXR1cm4geyFBcnJheX1cblx0ICovXG5cdHN0YXRpYyBzbGljZShhcnIsIHN0YXJ0LCBlbmQgPSBhcnIubGVuZ3RoKSB7XG5cdFx0Y29uc3Qgc2xpY2VkID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcblx0XHRcdHNsaWNlZC5wdXNoKGFycltpXSk7XG5cdFx0fVxuXHRcdHJldHVybiBzbGljZWQ7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgYXJyYXk7XG4iLCIvKiAhXG4gKiBQb2x5ZmlsbCBmcm9tIEdvb2dsZSdzIENsb3N1cmUgTGlicmFyeS5cbiAqIENvcHlyaWdodCAyMDEzIFRoZSBDbG9zdXJlIExpYnJhcnkgQXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7aXNTZXJ2ZXJTaWRlfSBmcm9tICcuLi9jb3JlTmFtZWQnO1xuXG5jb25zdCBhc3luYyA9IHt9O1xuXG4vKipcbiAqIFRocm93IGFuIGl0ZW0gd2l0aG91dCBpbnRlcnJ1cHRpbmcgdGhlIGN1cnJlbnQgZXhlY3V0aW9uIGNvbnRleHQuICBGb3JcbiAqIGV4YW1wbGUsIGlmIHByb2Nlc3NpbmcgYSBncm91cCBvZiBpdGVtcyBpbiBhIGxvb3AsIHNvbWV0aW1lcyBpdCBpcyB1c2VmdWxcbiAqIHRvIHJlcG9ydCBhbiBlcnJvciB3aGlsZSBzdGlsbCBhbGxvd2luZyB0aGUgcmVzdCBvZiB0aGUgYmF0Y2ggdG8gYmVcbiAqIHByb2Nlc3NlZC5cbiAqIEBwYXJhbSB7Kn0gZXhjZXB0aW9uXG4gKi9cbmFzeW5jLnRocm93RXhjZXB0aW9uID0gZnVuY3Rpb24oZXhjZXB0aW9uKSB7XG5cdC8vIEVhY2ggdGhyb3cgbmVlZHMgdG8gYmUgaW4gaXRzIG93biBjb250ZXh0LlxuXHRhc3luYy5uZXh0VGljayhmdW5jdGlvbigpIHtcblx0XHR0aHJvdyBleGNlcHRpb247XG5cdH0pO1xufTtcblxuLyoqXG4gKiBGaXJlcyB0aGUgcHJvdmlkZWQgY2FsbGJhY2sganVzdCBiZWZvcmUgdGhlIGN1cnJlbnQgY2FsbHN0YWNrIHVud2luZHMsIG9yIGFzXG4gKiBzb29uIGFzIHBvc3NpYmxlIGFmdGVyIHRoZSBjdXJyZW50IEpTIGV4ZWN1dGlvbiBjb250ZXh0LlxuICogQHBhcmFtIHtmdW5jdGlvbih0aGlzOlRISVMpfSBjYWxsYmFja1xuICogQHBhcmFtIHtUSElTPX0gY29udGV4dCBPYmplY3QgdG8gdXNlIGFzIHRoZSBcInRoaXMgdmFsdWVcIiB3aGVuIGNhbGxpbmdcbiAqICAgICB0aGUgcHJvdmlkZWQgZnVuY3Rpb24uXG4gKiBAdGVtcGxhdGUgVEhJU1xuICovXG5hc3luYy5ydW4gPSBmdW5jdGlvbihjYWxsYmFjaywgY29udGV4dCkge1xuXHRpZiAoIWFzeW5jLnJ1bi53b3JrUXVldWVTY2hlZHVsZWRfKSB7XG5cdFx0Ly8gTm90aGluZyBpcyBjdXJyZW50bHkgc2NoZWR1bGVkLCBzY2hlZHVsZSBpdCBub3cuXG5cdFx0YXN5bmMubmV4dFRpY2soYXN5bmMucnVuLnByb2Nlc3NXb3JrUXVldWUpO1xuXHRcdGFzeW5jLnJ1bi53b3JrUXVldWVTY2hlZHVsZWRfID0gdHJ1ZTtcblx0fVxuXG5cdGFzeW5jLnJ1bi53b3JrUXVldWVfLnB1c2gobmV3IGFzeW5jLnJ1bi5Xb3JrSXRlbV8oY2FsbGJhY2ssIGNvbnRleHQpKTtcbn07XG5cbi8qKiBAcHJpdmF0ZSB7Ym9vbGVhbn0gKi9cbmFzeW5jLnJ1bi53b3JrUXVldWVTY2hlZHVsZWRfID0gZmFsc2U7XG5cbi8qKiBAcHJpdmF0ZSB7IUFycmF5LjwhYXN5bmMucnVuLldvcmtJdGVtXz59ICovXG5hc3luYy5ydW4ud29ya1F1ZXVlXyA9IFtdO1xuXG4vKipcbiAqIFJ1biBhbnkgcGVuZGluZyBhc3luYy5ydW4gd29yayBpdGVtcy4gVGhpcyBmdW5jdGlvbiBpcyBub3QgaW50ZW5kZWRcbiAqIGZvciBnZW5lcmFsIHVzZSwgYnV0IGZvciB1c2UgYnkgZW50cnkgcG9pbnQgaGFuZGxlcnMgdG8gcnVuIGl0ZW1zIGFoZWFkIG9mXG4gKiBhc3luYy5uZXh0VGljay5cbiAqL1xuYXN5bmMucnVuLnByb2Nlc3NXb3JrUXVldWUgPSBmdW5jdGlvbigpIHtcblx0Ly8gTk9URTogYWRkaXRpb25hbCB3b3JrIHF1ZXVlIGl0ZW1zIG1heSBiZSBwdXNoZWQgd2hpbGUgcHJvY2Vzc2luZy5cblx0d2hpbGUgKGFzeW5jLnJ1bi53b3JrUXVldWVfLmxlbmd0aCkge1xuXHRcdC8vIERvbid0IGxldCB0aGUgd29yayBxdWV1ZSBncm93IGluZGVmaW5pdGVseS5cblx0XHRjb25zdCB3b3JrSXRlbXMgPSBhc3luYy5ydW4ud29ya1F1ZXVlXztcblx0XHRhc3luYy5ydW4ud29ya1F1ZXVlXyA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgd29ya0l0ZW1zLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCB3b3JrSXRlbSA9IHdvcmtJdGVtc1tpXTtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdHdvcmtJdGVtLmZuLmNhbGwod29ya0l0ZW0uc2NvcGUpO1xuXHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHRhc3luYy50aHJvd0V4Y2VwdGlvbihlKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBUaGVyZSBhcmUgbm8gbW9yZSB3b3JrIGl0ZW1zLCByZXNldCB0aGUgd29yayBxdWV1ZS5cblx0YXN5bmMucnVuLndvcmtRdWV1ZVNjaGVkdWxlZF8gPSBmYWxzZTtcbn07XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZmluYWxcbiAqIEBzdHJ1Y3RcbiAqIEBwcml2YXRlXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbigpfSBmblxuICogQHBhcmFtIHtPYmplY3R8bnVsbHx1bmRlZmluZWR9IHNjb3BlXG4gKi9cbmFzeW5jLnJ1bi5Xb3JrSXRlbV8gPSBmdW5jdGlvbihmbiwgc2NvcGUpIHtcblx0LyoqIEBjb25zdCAqL1xuXHR0aGlzLmZuID0gZm47XG5cdC8qKiBAY29uc3QgKi9cblx0dGhpcy5zY29wZSA9IHNjb3BlO1xufTtcblxuLyoqXG4gKiBGaXJlcyB0aGUgcHJvdmlkZWQgY2FsbGJhY2tzIGFzIHNvb24gYXMgcG9zc2libGUgYWZ0ZXIgdGhlIGN1cnJlbnQgSlNcbiAqIGV4ZWN1dGlvbiBjb250ZXh0LiBzZXRUaW1lb3V0KOKApiwgMCkgYWx3YXlzIHRha2VzIGF0IGxlYXN0IDVtcyBmb3IgbGVnYWN5XG4gKiByZWFzb25zLlxuICogQHBhcmFtIHtmdW5jdGlvbih0aGlzOlNDT1BFKX0gY2FsbGJhY2sgQ2FsbGJhY2sgZnVuY3Rpb24gdG8gZmlyZSBhcyBzb29uIGFzXG4gKiAgICAgcG9zc2libGUuXG4gKiBAcGFyYW0ge1NDT1BFPX0gY29udGV4dCBPYmplY3QgaW4gd2hvc2Ugc2NvcGUgdG8gY2FsbCB0aGUgbGlzdGVuZXIuXG4gKiBAdGVtcGxhdGUgU0NPUEVcbiAqL1xuYXN5bmMubmV4dFRpY2sgPSBmdW5jdGlvbihjYWxsYmFjaywgY29udGV4dCkge1xuXHRsZXQgY2IgPSBjYWxsYmFjaztcblx0aWYgKGNvbnRleHQpIHtcblx0XHRjYiA9IGNhbGxiYWNrLmJpbmQoY29udGV4dCk7XG5cdH1cblx0Y2IgPSBhc3luYy5uZXh0VGljay53cmFwQ2FsbGJhY2tfKGNiKTtcblx0Ly8gTG9vayBmb3IgYW5kIGNhY2hlIHRoZSBjdXN0b20gZmFsbGJhY2sgdmVyc2lvbiBvZiBzZXRJbW1lZGlhdGUuXG5cdGlmICghYXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXykge1xuXHRcdGlmIChcblx0XHRcdHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicgJiZcblx0XHRcdGlzU2VydmVyU2lkZSh7Y2hlY2tFbnY6IGZhbHNlfSlcblx0XHQpIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8gPSBzZXRJbW1lZGlhdGU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXHRcdFx0YXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyA9IGFzeW5jLm5leHRUaWNrLmdldFNldEltbWVkaWF0ZUVtdWxhdG9yXygpO1xuXHRcdH1cblx0fVxuXHRhc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfKGNiKTtcbn07XG5cbi8qKlxuICogQ2FjaGUgZm9yIHRoZSBzZXRJbW1lZGlhdGUgaW1wbGVtZW50YXRpb24uXG4gKiBAdHlwZSB7ZnVuY3Rpb24oZnVuY3Rpb24oKSl9XG4gKiBAcHJpdmF0ZVxuICovXG5hc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfID0gbnVsbDtcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHRoZSBiZXN0IHBvc3NpYmxlIGltcGxlbWVudGF0aW9uIHRvIHJ1biBhIGZ1bmN0aW9uIGFzIHNvb24gYXNcbiAqIHRoZSBKUyBldmVudCBsb29wIGlzIGlkbGUuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihmdW5jdGlvbigpKX0gVGhlIFwic2V0SW1tZWRpYXRlXCIgaW1wbGVtZW50YXRpb24uXG4gKiBAcHJpdmF0ZVxuICovXG5hc3luYy5uZXh0VGljay5nZXRTZXRJbW1lZGlhdGVFbXVsYXRvcl8gPSBmdW5jdGlvbigpIHtcblx0Ly8gQ3JlYXRlIGEgcHJpdmF0ZSBtZXNzYWdlIGNoYW5uZWwgYW5kIHVzZSBpdCB0byBwb3N0TWVzc2FnZSBlbXB0eSBtZXNzYWdlc1xuXHQvLyB0byBvdXJzZWx2ZXMuXG5cdGxldCBDaGFubmVsO1xuXG5cdC8vIFZlcmlmeSBpZiB2YXJpYWJsZSBpcyBkZWZpbmVkIG9uIHRoZSBjdXJyZW50IHJ1bnRpbWUgKGkuZS4sIG5vZGUsIGJyb3dzZXIpLlxuXHQvLyBDYW4ndCB1c2UgdHlwZW9mIGVuY2xvc2VkIGluIGEgZnVuY3Rpb24gKHN1Y2ggYXMgY29yZS5pc0Z1bmN0aW9uKSBvciBhblxuXHQvLyBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gd2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIGFuIGVudmlyb25tZW50XG5cdC8vIHdoZXJlIHRoZSB2YXJpYWJsZSBpcyB1bmRlZmluZWQuXG5cdGlmICh0eXBlb2YgTWVzc2FnZUNoYW5uZWwgPT09ICdmdW5jdGlvbicpIHtcblx0XHRDaGFubmVsID0gTWVzc2FnZUNoYW5uZWw7XG5cdH1cblxuXHQvLyBJZiBNZXNzYWdlQ2hhbm5lbCBpcyBub3QgYXZhaWxhYmxlIGFuZCB3ZSBhcmUgaW4gYSBicm93c2VyLCBpbXBsZW1lbnRcblx0Ly8gYW4gaWZyYW1lIGJhc2VkIHBvbHlmaWxsIGluIGJyb3dzZXJzIHRoYXQgaGF2ZSBwb3N0TWVzc2FnZSBhbmRcblx0Ly8gZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lci4gVGhlIGxhdHRlciBleGNsdWRlcyBJRTggYmVjYXVzZSBpdCBoYXMgYVxuXHQvLyBzeW5jaHJvbm91cyBwb3N0TWVzc2FnZSBpbXBsZW1lbnRhdGlvbi5cblx0aWYgKFxuXHRcdHR5cGVvZiBDaGFubmVsID09PSAndW5kZWZpbmVkJyAmJlxuXHRcdHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmXG5cdFx0d2luZG93LnBvc3RNZXNzYWdlICYmXG5cdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXJcblx0KSB7XG5cdFx0LyoqIEBjb25zdHJ1Y3RvciAqL1xuXHRcdENoYW5uZWwgPSBmdW5jdGlvbigpIHtcblx0XHRcdC8vIE1ha2UgYW4gZW1wdHksIGludmlzaWJsZSBpZnJhbWUuXG5cdFx0XHRjb25zdCBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcblx0XHRcdGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdFx0aWZyYW1lLnNyYyA9ICcnO1xuXHRcdFx0aWZyYW1lLnRpdGxlID0gJyc7XG5cdFx0XHRkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcblx0XHRcdGNvbnN0IHdpbiA9IGlmcmFtZS5jb250ZW50V2luZG93O1xuXHRcdFx0Y29uc3QgZG9jID0gd2luLmRvY3VtZW50O1xuXHRcdFx0ZG9jLm9wZW4oKTtcblx0XHRcdGRvYy53cml0ZSgnJyk7XG5cdFx0XHRkb2MuY2xvc2UoKTtcblx0XHRcdGNvbnN0IG1lc3NhZ2UgPSAnY2FsbEltbWVkaWF0ZScgKyBNYXRoLnJhbmRvbSgpO1xuXHRcdFx0Y29uc3Qgb3JpZ2luID0gd2luLmxvY2F0aW9uLnByb3RvY29sICsgJy8vJyArIHdpbi5sb2NhdGlvbi5ob3N0O1xuXHRcdFx0Y29uc3Qgb25tZXNzYWdlID0gZnVuY3Rpb24oZSkge1xuXHRcdFx0XHQvLyBWYWxpZGF0ZSBvcmlnaW4gYW5kIG1lc3NhZ2UgdG8gbWFrZSBzdXJlIHRoYXQgdGhpcyBtZXNzYWdlIHdhc1xuXHRcdFx0XHQvLyBpbnRlbmRlZCBmb3IgdXMuXG5cdFx0XHRcdGlmIChlLm9yaWdpbiAhPT0gb3JpZ2luICYmIGUuZGF0YSAhPT0gbWVzc2FnZSkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLnBvcnQxLm9ubWVzc2FnZSgpO1xuXHRcdFx0fS5iaW5kKHRoaXMpO1xuXHRcdFx0d2luLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbm1lc3NhZ2UsIGZhbHNlKTtcblx0XHRcdHRoaXMucG9ydDEgPSB7fTtcblx0XHRcdHRoaXMucG9ydDIgPSB7XG5cdFx0XHRcdHBvc3RNZXNzYWdlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHR3aW4ucG9zdE1lc3NhZ2UobWVzc2FnZSwgb3JpZ2luKTtcblx0XHRcdFx0fSxcblx0XHRcdH07XG5cdFx0fTtcblx0fVxuXHRpZiAodHlwZW9mIENoYW5uZWwgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0Y29uc3QgY2hhbm5lbCA9IG5ldyBDaGFubmVsKCk7XG5cdFx0Ly8gVXNlIGEgZmlmbyBsaW5rZWQgbGlzdCB0byBjYWxsIGNhbGxiYWNrcyBpbiB0aGUgcmlnaHQgb3JkZXIuXG5cdFx0bGV0IGhlYWQgPSB7fTtcblx0XHRsZXQgdGFpbCA9IGhlYWQ7XG5cdFx0Y2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdGhlYWQgPSBoZWFkLm5leHQ7XG5cdFx0XHRjb25zdCBjYiA9IGhlYWQuY2I7XG5cdFx0XHRoZWFkLmNiID0gbnVsbDtcblx0XHRcdGNiKCk7XG5cdFx0fTtcblx0XHRyZXR1cm4gZnVuY3Rpb24oY2IpIHtcblx0XHRcdHRhaWwubmV4dCA9IHtcblx0XHRcdFx0Y2I6IGNiLFxuXHRcdFx0fTtcblx0XHRcdHRhaWwgPSB0YWlsLm5leHQ7XG5cdFx0XHRjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKDApO1xuXHRcdH07XG5cdH1cblx0Ly8gSW1wbGVtZW50YXRpb24gZm9yIElFNi04OiBTY3JpcHQgZWxlbWVudHMgZmlyZSBhbiBhc3luY2hyb25vdXNcblx0Ly8gb25yZWFkeXN0YXRlY2hhbmdlIGV2ZW50IHdoZW4gaW5zZXJ0ZWQgaW50byB0aGUgRE9NLlxuXHRpZiAoXG5cdFx0dHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJlxuXHRcdCdvbnJlYWR5c3RhdGVjaGFuZ2UnIGluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpXG5cdCkge1xuXHRcdHJldHVybiBmdW5jdGlvbihjYikge1xuXHRcdFx0bGV0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXHRcdFx0c2NyaXB0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBDbGVhbiB1cCBhbmQgY2FsbCB0aGUgY2FsbGJhY2suXG5cdFx0XHRcdHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuXHRcdFx0XHRzY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzY3JpcHQpO1xuXHRcdFx0XHRzY3JpcHQgPSBudWxsO1xuXHRcdFx0XHRjYigpO1xuXHRcdFx0XHRjYiA9IG51bGw7XG5cdFx0XHR9O1xuXHRcdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHNjcmlwdCk7XG5cdFx0fTtcblx0fVxuXHQvLyBGYWxsIGJhY2sgdG8gc2V0VGltZW91dCB3aXRoIDAuIEluIGJyb3dzZXJzIHRoaXMgY3JlYXRlcyBhIGRlbGF5IG9mIDVtc1xuXHQvLyBvciBtb3JlLlxuXHRyZXR1cm4gZnVuY3Rpb24oY2IpIHtcblx0XHRzZXRUaW1lb3V0KGNiLCAwKTtcblx0fTtcbn07XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgaXMgb3ZlcnJpZGVkIHRvIHByb3RlY3QgY2FsbGJhY2tzIHdpdGggZW50cnkgcG9pbnRcbiAqIG1vbml0b3IgaWYgdGhlIGFwcGxpY2F0aW9uIG1vbml0b3JzIGVudHJ5IHBvaW50cy5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gY2FsbGJhY2sgQ2FsbGJhY2sgZnVuY3Rpb24gdG8gZmlyZSBhcyBzb29uIGFzIHBvc3NpYmxlLlxuICogQHJldHVybiB7ZnVuY3Rpb24oKX0gVGhlIHdyYXBwZWQgY2FsbGJhY2suXG4gKiBAcHJpdmF0ZVxuICovXG5hc3luYy5uZXh0VGljay53cmFwQ2FsbGJhY2tfID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcblx0cmV0dXJuIGNhbGxiYWNrO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgYXN5bmM7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogRGlzcG9zYWJsZSB1dGlsaXR5LiBXaGVuIGluaGVyaXRlZCBwcm92aWRlcyB0aGUgYGRpc3Bvc2VgIGZ1bmN0aW9uIHRvIGl0c1xuICogc3ViY2xhc3MsIHdoaWNoIGlzIHJlc3BvbnNpYmxlIGZvciBkaXNwb3Npbmcgb2YgYW55IG9iamVjdCByZWZlcmVuY2VzXG4gKiB3aGVuIGFuIGluc3RhbmNlIHdvbid0IGJlIHVzZWQgYW55bW9yZS4gU3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGVcbiAqIGBkaXNwb3NlSW50ZXJuYWxgIHRvIGltcGxlbWVudCBhbnkgc3BlY2lmaWMgZGlzcG9zaW5nIGxvZ2ljLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmNsYXNzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRGlzcG9zYWJsZSBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0LyoqXG5cdFx0ICogRmxhZyBpbmRpY2F0aW5nIGlmIHRoaXMgaW5zdGFuY2UgaGFzIGFscmVhZHkgYmVlbiBkaXNwb3NlZC5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5kaXNwb3NlZF8gPSBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBvZiB0aGlzIGluc3RhbmNlJ3Mgb2JqZWN0IHJlZmVyZW5jZXMuIENhbGxzIGBkaXNwb3NlSW50ZXJuYWxgLlxuXHQgKi9cblx0ZGlzcG9zZSgpIHtcblx0XHRpZiAoIXRoaXMuZGlzcG9zZWRfKSB7XG5cdFx0XHR0aGlzLmRpc3Bvc2VJbnRlcm5hbCgpO1xuXHRcdFx0dGhpcy5kaXNwb3NlZF8gPSB0cnVlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBpbXBsZW1lbnQgYW55IHNwZWNpZmljXG5cdCAqIGRpc3Bvc2luZyBsb2dpYyAobGlrZSBjbGVhcmluZyByZWZlcmVuY2VzIGFuZCBjYWxsaW5nIGBkaXNwb3NlYCBvbiBvdGhlclxuXHQgKiBkaXNwb3NhYmxlcykuXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhpcyBpbnN0YW5jZSBoYXMgYWxyZWFkeSBiZWVuIGRpc3Bvc2VkLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0aXNEaXNwb3NlZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5kaXNwb3NlZF87XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRGlzcG9zYWJsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBvYmplY3Qgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBvYmplY3Qge1xuXHQvKipcblx0ICogQ29waWVzIGFsbCB0aGUgbWVtYmVycyBvZiBhIHNvdXJjZSBvYmplY3QgdG8gYSB0YXJnZXQgb2JqZWN0LlxuXHQgKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0IFRhcmdldCBvYmplY3QuXG5cdCAqIEBwYXJhbSB7Li4uT2JqZWN0fSB2YXJfYXJncyBUaGUgb2JqZWN0cyBmcm9tIHdoaWNoIHZhbHVlcyB3aWxsIGJlIGNvcGllZC5cblx0ICogQHJldHVybiB7T2JqZWN0fSBSZXR1cm5zIHRoZSB0YXJnZXQgb2JqZWN0IHJlZmVyZW5jZS5cblx0ICovXG5cdHN0YXRpYyBtaXhpbih0YXJnZXQsIC4uLmFyZ3MpIHtcblx0XHRsZXQga2V5O1xuXHRcdGxldCBzb3VyY2U7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRzb3VyY2UgPSBhcmdzW2ldO1xuXHRcdFx0Ly8gUG9zc2libGUgcHJvdG90eXBlIGNoYWluIGxlYWssIGJyZWFrcyAxIG1ldGFsLWRvbSBhbmRcblx0XHRcdC8vIDEgbWV0YWwtaW5jcmVtZW50YWwtZG9tIHRlc3QgaWYgZ3VhcmQtZm9yLWluIHJ1bGUgaXMgYWRkcmVzc2VkXG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRcdGZvciAoa2V5IGluIHNvdXJjZSkge1xuXHRcdFx0XHR0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGFyZ2V0O1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYW4gb2JqZWN0IGJhc2VkIG9uIGl0cyBmdWxseSBxdWFsaWZpZWQgZXh0ZXJuYWwgbmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lLlxuXHQgKiBAcGFyYW0ge29iamVjdD19IHNjb3BlIFRoZSBvYmplY3Qgd2l0aGluIHdoaWNoIHRvIGxvb2s7IGRlZmF1bHQgaXNcblx0ICogICAgIDxjb2RlPndpbmRvdzwvY29kZT4uXG5cdCAqIEByZXR1cm4gez99IFRoZSB2YWx1ZSAob2JqZWN0IG9yIHByaW1pdGl2ZSkgb3IsIGlmIG5vdCBmb3VuZCwgdW5kZWZpbmVkLlxuXHQgKi9cblx0c3RhdGljIGdldE9iamVjdEJ5TmFtZShuYW1lLCBzY29wZSA9IHdpbmRvdykge1xuXHRcdGNvbnN0IHBhcnRzID0gbmFtZS5zcGxpdCgnLicpO1xuXHRcdHJldHVybiBwYXJ0cy5yZWR1Y2UoKHBhcnQsIGtleSkgPT4gcGFydFtrZXldLCBzY29wZSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhIG5ldyBvYmplY3Qgd2l0aCB0aGUgc2FtZSBrZXlzIGFzIHRoZSBnaXZlbiBvbmUsIGJ1dCB3aXRoXG5cdCAqIHRoZWlyIHZhbHVlcyBzZXQgdG8gdGhlIHJldHVybiB2YWx1ZXMgb2YgdGhlIHNwZWNpZmllZCBmdW5jdGlvbi5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBvYmpcblx0ICogQHBhcmFtIHshZnVuY3Rpb24oc3RyaW5nLCAqKX0gZm5cblx0ICogQHJldHVybiB7IU9iamVjdH1cblx0ICovXG5cdHN0YXRpYyBtYXAob2JqLCBmbikge1xuXHRcdGNvbnN0IG1hcHBlZE9iaiA9IHt9O1xuXHRcdGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0bWFwcGVkT2JqW2tleXNbaV1dID0gZm4oa2V5c1tpXSwgb2JqW2tleXNbaV1dKTtcblx0XHR9XG5cdFx0cmV0dXJuIG1hcHBlZE9iajtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIHR3byBnaXZlbiBvYmplY3RzIGFyZSBlcXVhbC4gVGhpcyBpcyBkb25lIHZpYSBhIHNoYWxsb3dcblx0ICogY2hlY2ssIGluY2x1ZGluZyBvbmx5IHRoZSBrZXlzIGRpcmVjdGx5IGNvbnRhaW5lZCBieSB0aGUgMiBvYmplY3RzLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb2JqMVxuXHQgKiBAcGFyYW0ge09iamVjdH0gb2JqMlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIHNoYWxsb3dFcXVhbChvYmoxLCBvYmoyKSB7XG5cdFx0aWYgKG9iajEgPT09IG9iajIpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdGNvbnN0IGtleXMxID0gT2JqZWN0LmtleXMob2JqMSk7XG5cdFx0Y29uc3Qga2V5czIgPSBPYmplY3Qua2V5cyhvYmoyKTtcblx0XHRpZiAoa2V5czEubGVuZ3RoICE9PSBrZXlzMi5sZW5ndGgpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMxLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAob2JqMVtrZXlzMVtpXV0gIT09IG9iajJba2V5czFbaV1dKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb2JqZWN0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFNldCBvZiB1dGlsaXRpZXMgZm9yIHN0cmluZyBvcGVyYXRpb25zXG4gKi9cbmNsYXNzIHN0cmluZyB7XG5cdC8qKlxuXHQgKiBDb21wYXJlcyB0aGUgZ2l2ZW4gc3RyaW5ncyB3aXRob3V0IHRha2luZyB0aGUgY2FzZSBpbnRvIGFjY291bnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gc3RyMVxuXHQgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHN0cjJcblx0ICogQHJldHVybiB7bnVtYmVyfSBFaXRoZXIgLTEsIDAgb3IgMSwgYWNjb3JkaW5nIHRvIGlmIHRoZSBmaXJzdCBzdHJpbmcgaXNcblx0ICogICAgIFwic21hbGxlclwiLCBlcXVhbCBvciBcImJpZ2dlclwiIHRoYW4gdGhlIHNlY29uZCBnaXZlbiBzdHJpbmcuXG5cdCAqL1xuXHRzdGF0aWMgY2FzZUluc2Vuc2l0aXZlQ29tcGFyZShzdHIxLCBzdHIyKSB7XG5cdFx0Y29uc3QgdGVzdDEgPSBTdHJpbmcoc3RyMSkudG9Mb3dlckNhc2UoKTtcblx0XHRjb25zdCB0ZXN0MiA9IFN0cmluZyhzdHIyKS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0aWYgKHRlc3QxIDwgdGVzdDIpIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9IGVsc2UgaWYgKHRlc3QxID09PSB0ZXN0Mikge1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiAxO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHRoZSBicmVha2luZyBzcGFjZXMgZnJvbSB0aGUgbGVmdCBhbmQgcmlnaHQgb2YgdGhlIHN0cmluZyBhbmRcblx0ICogY29sbGFwc2VzIHRoZSBzZXF1ZW5jZXMgb2YgYnJlYWtpbmcgc3BhY2VzIGluIHRoZSBtaWRkbGUgaW50byBzaW5nbGUgc3BhY2VzLlxuXHQgKiBUaGUgb3JpZ2luYWwgYW5kIHRoZSByZXN1bHQgc3RyaW5ncyByZW5kZXIgdGhlIHNhbWUgd2F5IGluIEhUTUwuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgQSBzdHJpbmcgaW4gd2hpY2ggdG8gY29sbGFwc2Ugc3BhY2VzLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IENvcHkgb2YgdGhlIHN0cmluZyB3aXRoIG5vcm1hbGl6ZWQgYnJlYWtpbmcgc3BhY2VzLlxuXHQgKi9cblx0c3RhdGljIGNvbGxhcHNlQnJlYWtpbmdTcGFjZXMoc3RyKSB7XG5cdFx0cmV0dXJuIHN0clxuXHRcdFx0LnJlcGxhY2UoL1tcXHRcXHJcXG4gXSsvZywgJyAnKVxuXHRcdFx0LnJlcGxhY2UoL15bXFx0XFxyXFxuIF0rfFtcXHRcXHJcXG4gXSskL2csICcnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFc2NhcGVzIGNoYXJhY3RlcnMgaW4gdGhlIHN0cmluZyB0aGF0IGFyZSBub3Qgc2FmZSB0byB1c2UgaW4gYSBSZWdFeHAuXG5cdCAqIEBwYXJhbSB7Kn0gc3RyIFRoZSBzdHJpbmcgdG8gZXNjYXBlLiBJZiBub3QgYSBzdHJpbmcsIGl0IHdpbGwgYmUgY2FzdGVkXG5cdCAqICAgICB0byBvbmUuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQSBSZWdFeHAgc2FmZSwgZXNjYXBlZCBjb3B5IG9mIHtAY29kZSBzfS5cblx0ICovXG5cdHN0YXRpYyBlc2NhcGVSZWdleChzdHIpIHtcblx0XHRyZXR1cm4gU3RyaW5nKHN0cilcblx0XHRcdC5yZXBsYWNlKC8oWy0oKVtcXF17fSs/Ki4kXnwsOiM8IVxcXFxdKS9nLCAnXFxcXCQxJylcblx0XHRcdC5yZXBsYWNlKC9cXHgwOC9nLCAnXFxcXHgwOCcpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhIHN0cmluZyB3aXRoIGF0IGxlYXN0IDY0LWJpdHMgb2YgcmFuZG9tbmVzcy5cblx0ICogQHJldHVybiB7c3RyaW5nfSBBIHJhbmRvbSBzdHJpbmcsIGUuZy4gc24xczd2YjRnY2ljLlxuXHQgKi9cblx0c3RhdGljIGdldFJhbmRvbVN0cmluZygpIHtcblx0XHRjb25zdCB4ID0gMjE0NzQ4MzY0ODtcblx0XHRyZXR1cm4gKFxuXHRcdFx0TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogeCkudG9TdHJpbmcoMzYpICtcblx0XHRcdE1hdGguYWJzKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHgpIF4gRGF0ZS5ub3coKSkudG9TdHJpbmcoMzYpXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxjdWxhdGVzIHRoZSBoYXNoY29kZSBmb3IgYSBzdHJpbmcuIFRoZSBoYXNoY29kZSB2YWx1ZSBpcyBjb21wdXRlZCBieVxuXHQgKiB0aGUgc3VtIGFsZ29yaXRobTogc1swXSozMV4obi0xKSArIHNbMV0qMzFeKG4tMikgKyAuLi4gKyBzW24tMV0uIEEgbmljZVxuXHQgKiBwcm9wZXJ0eSBvZiB1c2luZyAzMSBwcmltZSBpcyB0aGF0IHRoZSBtdWx0aXBsaWNhdGlvbiBjYW4gYmUgcmVwbGFjZWQgYnlcblx0ICogYSBzaGlmdCBhbmQgYSBzdWJ0cmFjdGlvbiBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlOiAzMSppID09IChpPDw1KS1pLlxuXHQgKiBNb2Rlcm4gVk1zIGRvIHRoaXMgc29ydCBvZiBvcHRpbWl6YXRpb24gYXV0b21hdGljYWxseS5cblx0ICogQHBhcmFtIHtTdHJpbmd9IHZhbCBUYXJnZXQgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtOdW1iZXJ9IFJldHVybnMgdGhlIHN0cmluZyBoYXNoY29kZS5cblx0ICovXG5cdHN0YXRpYyBoYXNoQ29kZSh2YWwpIHtcblx0XHRsZXQgaGFzaCA9IDA7XG5cdFx0Zm9yIChsZXQgaSA9IDAsIGxlbiA9IHZhbC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0aGFzaCA9IDMxICogaGFzaCArIHZhbC5jaGFyQ29kZUF0KGkpO1xuXHRcdFx0aGFzaCAlPSAweDEwMDAwMDAwMDtcblx0XHR9XG5cdFx0cmV0dXJuIGhhc2g7XG5cdH1cblxuXHQvKipcblx0ICogUmVwbGFjZXMgaW50ZXJ2YWwgaW50byB0aGUgc3RyaW5nIHdpdGggc3BlY2lmaWVkIHZhbHVlLCBlLmcuXG5cdCAqIGByZXBsYWNlSW50ZXJ2YWwoXCJhYmNkZVwiLCAxLCA0LCBcIlwiKWAgcmV0dXJucyBcImFlXCIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIGlucHV0IHN0cmluZy5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0IFN0YXJ0IGludGVydmFsIHBvc2l0aW9uIHRvIGJlIHJlcGxhY2VkLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gZW5kIEVuZCBpbnRlcnZhbCBwb3NpdGlvbiB0byBiZSByZXBsYWNlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIFRoZSB2YWx1ZSB0aGF0IHJlcGxhY2VzIHRoZSBzcGVjaWZpZWQgaW50ZXJ2YWwuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdHN0YXRpYyByZXBsYWNlSW50ZXJ2YWwoc3RyLCBzdGFydCwgZW5kLCB2YWx1ZSkge1xuXHRcdHJldHVybiBzdHIuc3Vic3RyaW5nKDAsIHN0YXJ0KSArIHZhbHVlICsgc3RyLnN1YnN0cmluZyhlbmQpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHN0cmluZztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBQYXJzZXMgdGhlIGdpdmVuIHVyaSBzdHJpbmcgaW50byBhbiBvYmplY3QuXG4gKiBAcGFyYW0geyo9fSBvcHRfdXJpIE9wdGlvbmFsIHN0cmluZyBVUkkgdG8gcGFyc2VcbiAqL1xuZnVuY3Rpb24gcGFyc2VGcm9tQW5jaG9yKG9wdF91cmkpIHtcblx0dmFyIGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG5cdGxpbmsuaHJlZiA9IG9wdF91cmk7XG5cblx0aWYobGluay5wcm90b2NvbCA9PT0gJzonIHx8ICEvOi8udGVzdChsaW5rLmhyZWYpKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgJHtvcHRfdXJpfSBpcyBub3QgYSB2YWxpZCBVUkxgKTtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0aGFzaDogbGluay5oYXNoLFxuXHRcdGhvc3RuYW1lOiBsaW5rLmhvc3RuYW1lLFxuXHRcdHBhc3N3b3JkOiBsaW5rLnBhc3N3b3JkLFxuXHRcdHBhdGhuYW1lOiBsaW5rLnBhdGhuYW1lWzBdID09PSAnLycgPyBsaW5rLnBhdGhuYW1lIDogJy8nICsgbGluay5wYXRobmFtZSxcblx0XHRwb3J0OiBsaW5rLnBvcnQsXG5cdFx0cHJvdG9jb2w6IGxpbmsucHJvdG9jb2wsXG5cdFx0c2VhcmNoOiBsaW5rLnNlYXJjaCxcblx0XHR1c2VybmFtZTogbGluay51c2VybmFtZVxuXHR9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBwYXJzZUZyb21BbmNob3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGlzRnVuY3Rpb24gfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgcGFyc2VGcm9tQW5jaG9yIGZyb20gJy4vcGFyc2VGcm9tQW5jaG9yJztcblxuLyoqXG4gKiBQYXJzZXMgdGhlIGdpdmVuIHVyaSBzdHJpbmcgaW50byBhbiBvYmplY3QuIFRoZSBVUkwgZnVuY3Rpb24gd2lsbCBiZSB1c2VkXG4gKiB3aGVuIHByZXNlbnQsIG90aGVyd2lzZSB3ZSdsbCBmYWxsIGJhY2sgdG8gdGhlIGFuY2hvciBub2RlIGVsZW1lbnQuXG4gKiBAcGFyYW0geyo9fSBvcHRfdXJpIE9wdGlvbmFsIHN0cmluZyBVUkkgdG8gcGFyc2VcbiAqL1xuZnVuY3Rpb24gcGFyc2Uob3B0X3VyaSkge1xuXHRpZiAoaXNGdW5jdGlvbihVUkwpICYmIFVSTC5sZW5ndGgpIHtcblx0XHRjb25zdCB1cmwgPSBuZXcgVVJMKG9wdF91cmkpO1xuXG5cdFx0Ly8gU2FmYXJpIEJyb3dzZXJzIHdpbGwgY2FwIHBvcnQgdG8gdGhlIG1heCAxNi1iaXQgdW5zaWduZWQgaW50ZWdlciAoNjU1MzUpIGluc3RlYWRcblx0XHQvLyBvZiB0aHJvd2luZyBhIFR5cGVFcnJvciBhcyBwZXIgc3BlYy4gSXQgd2lsbCBzdGlsbCBrZWVwIHRoZSBwb3J0IG51bWJlciBpbiB0aGVcblx0XHQvLyBocmVmIGF0dHJpYnV0ZSwgc28gd2UgY2FuIHVzZSB0aGlzIG1pc21hdGNoIHRvIHJhaXNlIHRoZSBleHBlY3RlZCBleGNlcHRpb24uXG5cdFx0aWYgKHVybC5wb3J0ICYmIHVybC5ocmVmLmluZGV4T2YodXJsLnBvcnQpID09PSAtMSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgJHtvcHRfdXJpfSBpcyBub3QgYSB2YWxpZCBVUkxgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdXJsO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBwYXJzZUZyb21BbmNob3Iob3B0X3VyaSk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgcGFyc2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IERpc3Bvc2FibGUgfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogQSBjYWNoZWQgcmVmZXJlbmNlIHRvIHRoZSBjcmVhdGUgZnVuY3Rpb24uXG4gKi9cbnZhciBjcmVhdGUgPSBPYmplY3QuY3JlYXRlO1xuXG4vKipcbiAqIENhc2UgaW5zZW5zaXRpdmUgc3RyaW5nIE11bHRpbWFwIGltcGxlbWVudGF0aW9uLiBBbGxvd3MgbXVsdGlwbGUgdmFsdWVzIGZvclxuICogdGhlIHNhbWUga2V5IG5hbWUuXG4gKiBAZXh0ZW5kcyB7RGlzcG9zYWJsZX1cbiAqL1xuY2xhc3MgTXVsdGlNYXAgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblx0XHR0aGlzLmtleXMgPSBjcmVhdGUobnVsbCk7XG5cdFx0dGhpcy52YWx1ZXMgPSBjcmVhdGUobnVsbCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB2YWx1ZSB0byBhIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcGFyYW0geyp9IHZhbHVlXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZChuYW1lLCB2YWx1ZSkge1xuXHRcdHRoaXMua2V5c1tuYW1lLnRvTG93ZXJDYXNlKCldID0gbmFtZTtcblx0XHR0aGlzLnZhbHVlc1tuYW1lLnRvTG93ZXJDYXNlKCldID0gdGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXSB8fCBbXTtcblx0XHR0aGlzLnZhbHVlc1tuYW1lLnRvTG93ZXJDYXNlKCldLnB1c2godmFsdWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFycyBtYXAgbmFtZXMgYW5kIHZhbHVlcy5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0Y2xlYXIoKSB7XG5cdFx0dGhpcy5rZXlzID0gY3JlYXRlKG51bGwpO1xuXHRcdHRoaXMudmFsdWVzID0gY3JlYXRlKG51bGwpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBtYXAgY29udGFpbnMgYSB2YWx1ZSB0byB0aGUga2V5IG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGNvbnRhaW5zKG5hbWUpIHtcblx0XHRyZXR1cm4gbmFtZS50b0xvd2VyQ2FzZSgpIGluIHRoaXMudmFsdWVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy52YWx1ZXMgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBgTXVsdGlNYXBgIGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIG9iamVjdC5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBvYmpcblx0ICogQHJldHVybiB7IU11bHRpTWFwfVxuXHQgKi9cblx0c3RhdGljIGZyb21PYmplY3Qob2JqKSB7XG5cdFx0dmFyIG1hcCA9IG5ldyBNdWx0aU1hcCgpO1xuXHRcdHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG1hcC5zZXQoa2V5c1tpXSwgb2JqW2tleXNbaV1dKTtcblx0XHR9XG5cdFx0cmV0dXJuIG1hcDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBmaXJzdCBhZGRlZCB2YWx1ZSBmcm9tIGEga2V5IG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG5cdCAqIEByZXR1cm4geyp9XG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGdldChuYW1lKSB7XG5cdFx0dmFyIHZhbHVlcyA9IHRoaXMudmFsdWVzW25hbWUudG9Mb3dlckNhc2UoKV07XG5cdFx0aWYgKHZhbHVlcykge1xuXHRcdFx0cmV0dXJuIHZhbHVlc1swXTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBhbGwgdmFsdWVzIGZyb20gYSBrZXkgbmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHJldHVybiB7QXJyYXkuPCo+fVxuXHQgKi9cblx0Z2V0QWxsKG5hbWUpIHtcblx0XHRyZXR1cm4gdGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRydWUgaWYgdGhlIG1hcCBpcyBlbXB0eSwgZmFsc2Ugb3RoZXJ3aXNlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0aXNFbXB0eSgpIHtcblx0XHRyZXR1cm4gdGhpcy5zaXplKCkgPT09IDA7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBhcnJheSBvZiBrZXkgbmFtZXMuXG5cdCAqIEByZXR1cm4ge0FycmF5LjxzdHJpbmc+fVxuXHQgKi9cblx0bmFtZXMoKSB7XG5cdFx0cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMudmFsdWVzKS5tYXAoKGtleSkgPT4gdGhpcy5rZXlzW2tleV0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIHZhbHVlcyBmcm9tIGEga2V5IG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHJlbW92ZShuYW1lKSB7XG5cdFx0ZGVsZXRlIHRoaXMua2V5c1tuYW1lLnRvTG93ZXJDYXNlKCldO1xuXHRcdGRlbGV0ZSB0aGlzLnZhbHVlc1tuYW1lLnRvTG93ZXJDYXNlKCldO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHZhbHVlIG9mIGEga2V5IG5hbWUuIFJlbGV2YW50IHRvIHJlcGxhY2UgdGhlIGN1cnJlbnQgdmFsdWVzIHdpdGhcblx0ICogYSBuZXcgb25lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcGFyYW0geyp9IHZhbHVlXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldChuYW1lLCB2YWx1ZSkge1xuXHRcdHRoaXMua2V5c1tuYW1lLnRvTG93ZXJDYXNlKCldID0gbmFtZTtcblx0XHR0aGlzLnZhbHVlc1tuYW1lLnRvTG93ZXJDYXNlKCldID0gW3ZhbHVlXTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzaXplIG9mIHRoZSBtYXAga2V5IG5hbWVzLlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRzaXplKCkge1xuXHRcdHJldHVybiB0aGlzLm5hbWVzKCkubGVuZ3RoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHBhcnNlZCB2YWx1ZXMgYXMgYSBzdHJpbmcuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLnZhbHVlcyk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTXVsdGlNYXA7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGFycmF5IH0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEdlbmVyaWMgdHJlZSBub2RlIGRhdGEgc3RydWN0dXJlIHdpdGggYXJiaXRyYXJ5IG51bWJlciBvZiBjaGlsZCBub2Rlcy5cbiAqIEBwYXJhbSB7Vn0gdmFsdWUgVmFsdWUuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuY2xhc3MgVHJlZU5vZGUge1xuXG5cdGNvbnN0cnVjdG9yKHZhbHVlKSB7XG5cdFx0LyoqXG5cdFx0ICogVGhlIHZhbHVlLlxuXHRcdCAqIEBwcml2YXRlIHtWfVxuXHRcdCAqL1xuXHRcdHRoaXMudmFsdWVfID0gdmFsdWU7XG5cblx0XHQvKipcblx0XHQgKiBSZWZlcmVuY2UgdG8gdGhlIHBhcmVudCBub2RlIG9yIG51bGwgaWYgaXQgaGFzIG5vIHBhcmVudC5cblx0XHQgKiBAcHJpdmF0ZSB7VHJlZU5vZGV9XG5cdFx0ICovXG5cdFx0dGhpcy5wYXJlbnRfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIENoaWxkIG5vZGVzIG9yIG51bGwgaW4gY2FzZSBvZiBsZWFmIG5vZGUuXG5cdFx0ICogQHByaXZhdGUge0FycmF5PCFUcmVlTm9kZT59XG5cdFx0ICovXG5cdFx0dGhpcy5jaGlsZHJlbl8gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFwcGVuZHMgYSBjaGlsZCBub2RlIHRvIHRoaXMgbm9kZS5cblx0ICogQHBhcmFtIHshVHJlZU5vZGV9IGNoaWxkIE9ycGhhbiBjaGlsZCBub2RlLlxuXHQgKi9cblx0YWRkQ2hpbGQoY2hpbGQpIHtcblx0XHRhc3NlcnRDaGlsZEhhc05vUGFyZW50KGNoaWxkKTtcblx0XHRjaGlsZC5zZXRQYXJlbnQodGhpcyk7XG5cdFx0dGhpcy5jaGlsZHJlbl8gPSB0aGlzLmNoaWxkcmVuXyB8fCBbXTtcblx0XHR0aGlzLmNoaWxkcmVuXy5wdXNoKGNoaWxkKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUZWxscyB3aGV0aGVyIHRoaXMgbm9kZSBpcyB0aGUgYW5jZXN0b3Igb2YgdGhlIGdpdmVuIG5vZGUuXG5cdCAqIEBwYXJhbSB7IVRyZWVOb2RlfSBub2RlIEEgbm9kZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGlzIG5vZGUgaXMgdGhlIGFuY2VzdG9yIG9mIHtAY29kZSBub2RlfS5cblx0ICovXG5cdGNvbnRhaW5zKG5vZGUpIHtcblx0XHRsZXQgY3VycmVudCA9IG5vZGUuZ2V0UGFyZW50KCk7XG5cdFx0d2hpbGUgKGN1cnJlbnQpIHtcblx0XHRcdGlmIChjdXJyZW50ID09PSB0aGlzKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0Y3VycmVudCA9IGN1cnJlbnQuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHshQXJyYXk8VHJlZU5vZGU+fSBBbGwgYW5jZXN0b3Igbm9kZXMgaW4gYm90dG9tLXVwIG9yZGVyLlxuXHQgKi9cblx0Z2V0QW5jZXN0b3JzKCkge1xuXHRcdGxldCBhbmNlc3RvcnMgPSBbXTtcblx0XHRsZXQgbm9kZSA9IHRoaXMuZ2V0UGFyZW50KCk7XG5cdFx0d2hpbGUgKG5vZGUpIHtcblx0XHRcdGFuY2VzdG9ycy5wdXNoKG5vZGUpO1xuXHRcdFx0bm9kZSA9IG5vZGUuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiBhbmNlc3RvcnM7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY2hpbGQgbm9kZSBvZiB0aGlzIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LlxuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggQ2hpbGQgaW5kZXguXG5cdCAqIEByZXR1cm4gez9UcmVlTm9kZX0gVGhlIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4XG5cdCAqIG9yIG51bGwgaWYgbm90IGZvdW5kLlxuXHQgKi9cblx0Z2V0Q2hpbGRBdChpbmRleCkge1xuXHRcdHJldHVybiB0aGlzLmdldENoaWxkcmVuKClbaW5kZXhdIHx8IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7P0FycmF5PCFUcmVlTm9kZT59IENoaWxkIG5vZGVzIG9yIG51bGwgaW4gY2FzZSBvZiBsZWFmIG5vZGUuXG5cdCAqL1xuXHRnZXRDaGlsZHJlbigpIHtcblx0XHRyZXR1cm4gdGhpcy5jaGlsZHJlbl8gfHwgVHJlZU5vZGUuRU1QVFlfQVJSQVk7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGNoaWxkcmVuLlxuXHQgKi9cblx0Z2V0Q2hpbGRDb3VudCgpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRDaGlsZHJlbigpLmxlbmd0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgYW5jZXN0b3JzIG9mIHRoZSBub2RlLlxuXHQgKi9cblx0Z2V0RGVwdGgoKSB7XG5cdFx0bGV0IGRlcHRoID0gMDtcblx0XHRsZXQgbm9kZSA9IHRoaXM7XG5cdFx0d2hpbGUgKG5vZGUuZ2V0UGFyZW50KCkpIHtcblx0XHRcdGRlcHRoKys7XG5cdFx0XHRub2RlID0gbm9kZS5nZXRQYXJlbnQoKTtcblx0XHR9XG5cdFx0cmV0dXJuIGRlcHRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4gez9UcmVlTm9kZX0gUGFyZW50IG5vZGUgb3IgbnVsbCBpZiBpdCBoYXMgbm8gcGFyZW50LlxuXHQgKi9cblx0Z2V0UGFyZW50KCkge1xuXHRcdHJldHVybiB0aGlzLnBhcmVudF87XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7IVRyZWVOb2RlfSBUaGUgcm9vdCBvZiB0aGUgdHJlZSBzdHJ1Y3R1cmUsIGkuZS4gdGhlIGZhcnRoZXN0XG5cdCAqIGFuY2VzdG9yIG9mIHRoZSBub2RlIG9yIHRoZSBub2RlIGl0c2VsZiBpZiBpdCBoYXMgbm8gcGFyZW50cy5cblx0ICovXG5cdGdldFJvb3QoKSB7XG5cdFx0bGV0IHJvb3QgPSB0aGlzO1xuXHRcdHdoaWxlIChyb290LmdldFBhcmVudCgpKSB7XG5cdFx0XHRyb290ID0gcm9vdC5nZXRQYXJlbnQoKTtcblx0XHR9XG5cdFx0cmV0dXJuIHJvb3Q7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgdmFsdWUuXG5cdCAqIEByZXR1cm4ge1Z9IFRoZSB2YWx1ZS5cblx0ICovXG5cdGdldFZhbHVlKCkge1xuXHRcdHJldHVybiB0aGlzLnZhbHVlXztcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSBub2RlIGlzIGEgbGVhZiBub2RlLlxuXHQgKi9cblx0aXNMZWFmKCkge1xuXHRcdHJldHVybiAhdGhpcy5nZXRDaGlsZENvdW50KCk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgZ2l2ZW4gY2hpbGQgbm9kZSBvZiB0aGlzIG5vZGUuXG5cdCAqIEBwYXJhbSB7VHJlZU5vZGV9IGNoaWxkIFRoZSBub2RlIHRvIHJlbW92ZS5cblx0ICogQHJldHVybiB7VHJlZU5vZGV9IFRoZSByZW1vdmVkIG5vZGUgaWYgYW55LCBudWxsIG90aGVyd2lzZS5cblx0ICovXG5cdHJlbW92ZUNoaWxkKGNoaWxkKSB7XG5cdFx0aWYgKGFycmF5LnJlbW92ZSh0aGlzLmdldENoaWxkcmVuKCksIGNoaWxkKSkge1xuXHRcdFx0cmV0dXJuIGNoaWxkO1xuXHRcdH1cblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwYXJlbnQgbm9kZSBvZiB0aGlzIG5vZGUuIFRoZSBjYWxsZXJzIG11c3QgZW5zdXJlIHRoYXQgdGhlXG5cdCAqIHBhcmVudCBub2RlIGFuZCBvbmx5IHRoYXQgaGFzIHRoaXMgbm9kZSBhbW9uZyBpdHMgY2hpbGRyZW4uXG5cdCAqIEBwYXJhbSB7VHJlZU5vZGV9IHBhcmVudCBUaGUgcGFyZW50IHRvIHNldC4gSWYgbnVsbCwgdGhlIG5vZGUgd2lsbCBiZVxuXHQgKiBkZXRhY2hlZCBmcm9tIHRoZSB0cmVlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzZXRQYXJlbnQocGFyZW50KSB7XG5cdFx0dGhpcy5wYXJlbnRfID0gcGFyZW50O1xuXHR9XG5cblx0LyoqXG5cdCAqIFRyYXZlcnNlcyB0aGUgc3VidHJlZS4gVGhlIGZpcnN0IGNhbGxiYWNrIHN0YXJ0cyB3aXRoIHRoaXMgbm9kZSxcblx0ICogYW5kIHZpc2l0cyB0aGUgZGVzY2VuZGFudCBub2RlcyBkZXB0aC1maXJzdCwgaW4gcHJlb3JkZXIuXG5cdCAqIFRoZSBzZWNvbmQgY2FsbGJhY2ssIHN0YXJ0cyB3aXRoIGRlZXBlc3QgY2hpbGQgdGhlbiB2aXNpdHNcblx0ICogdGhlIGFuY2VzdG9yIG5vZGVzIGRlcHRoLWZpcnN0LCBpbiBwb3N0b3JkZXIuIEUuZy5cblx0ICpcblx0ICogIFx0IEFcblx0ICogICAgLyBcXFxuXHQgKiAgIEIgICBDXG5cdCAqICAvICAgLyBcXFxuXHQgKiBEICAgRSAgIEZcblx0ICpcblx0ICogcHJlb3JkZXIgLT4gWydBJywgJ0InLCAnRCcsICdDJywgJ0UnLCAnRiddXG5cdCAqIHBvc3RvcmRlciAtPiBbJ0QnLCAnQicsICdFJywgJ0YnLCAnQycsICdBJ11cblx0ICpcblx0ICogQHBhcmFtIHtmdW5jdGlvbj19IG9wdF9wcmVvcmRlckZuIFRoZSBjYWxsYmFjayB0byBleGVjdXRlIHdoZW4gdmlzaXRpbmcgYSBub2RlLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uPX0gb3B0X3Bvc3RvcmRlckZuIFRoZSBjYWxsYmFjayB0byBleGVjdXRlIGJlZm9yZSBsZWF2aW5nIGEgbm9kZS5cblx0ICovXG5cdHRyYXZlcnNlKG9wdF9wcmVvcmRlckZuLCBvcHRfcG9zdG9yZGVyRm4pIHtcblx0XHRpZiAob3B0X3ByZW9yZGVyRm4pIHtcblx0XHRcdG9wdF9wcmVvcmRlckZuKHRoaXMpO1xuXHRcdH1cblx0XHR0aGlzLmdldENoaWxkcmVuKCkuZm9yRWFjaCgoY2hpbGQpID0+IGNoaWxkLnRyYXZlcnNlKG9wdF9wcmVvcmRlckZuLCBvcHRfcG9zdG9yZGVyRm4pKTtcblx0XHRpZiAob3B0X3Bvc3RvcmRlckZuKSB7XG5cdFx0XHRvcHRfcG9zdG9yZGVyRm4odGhpcyk7XG5cdFx0fVxuXHR9XG5cbn1cblxuLyoqXG4gKiBDb25zdGFudCBmb3IgZW1wdHkgYXJyYXkgdG8gYXZvaWQgdW5uZWNlc3NhcnkgYWxsb2NhdGlvbnMuXG4gKiBAcHJpdmF0ZVxuICovXG5UcmVlTm9kZS5FTVBUWV9BUlJBWSA9IFtdO1xuXG4vKipcbiAqIEFzc2VydHMgdGhhdCBjaGlsZCBoYXMgbm8gcGFyZW50LlxuICogQHBhcmFtIHtUcmVlTm9kZX0gY2hpbGQgQSBjaGlsZC5cbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IGFzc2VydENoaWxkSGFzTm9QYXJlbnQgPSBmdW5jdGlvbihjaGlsZCkge1xuXHRpZiAoY2hpbGQuZ2V0UGFyZW50KCkpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBhZGQgY2hpbGQgd2l0aCBwYXJlbnQuJyk7XG5cdH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFRyZWVOb2RlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0RlZiwgc3RyaW5nIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHBhcnNlIGZyb20gJy4vcGFyc2UnO1xuaW1wb3J0IHsgTXVsdGlNYXAgfSBmcm9tICdtZXRhbC1zdHJ1Y3RzJztcblxudmFyIHBhcnNlRm5fID0gcGFyc2U7XG5cbmNsYXNzIFVyaSB7XG5cblx0LyoqXG5cdCAqIFRoaXMgY2xhc3MgY29udGFpbnMgc2V0dGVycyBhbmQgZ2V0dGVycyBmb3IgdGhlIHBhcnRzIG9mIHRoZSBVUkkuXG5cdCAqIFRoZSBmb2xsb3dpbmcgZmlndXJlIGRpc3BsYXlzIGFuIGV4YW1wbGUgVVJJcyBhbmQgdGhlaXIgY29tcG9uZW50IHBhcnRzLlxuXHQgKlxuXHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoXG5cdCAqXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUjOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUkFxuXHQgKlx0ICBhYmM6Ly9leGFtcGxlLmNvbToxMjMvcGF0aC9kYXRhP2tleT12YWx1ZSNmcmFnaWQxXG5cdCAqXHQgIOKUlOKUrOKUmCAgIOKUlOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUmCDilJTilKzilJggICAgICAgICAgIOKUlOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUmCDilJTilIDilIDilKzilIDilIDilJhcblx0ICogcHJvdG9jb2wgIGhvc3RuYW1lICBwb3J0ICAgICAgICAgICAgc2VhcmNoICAgIGhhc2hcblx0ICogICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSs4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYXG5cdCAqICAgICAgICAgICAgICAgIGhvc3Rcblx0ICpcblx0ICogQHBhcmFtIHsqPX0gb3B0X3VyaSBPcHRpb25hbCBzdHJpbmcgVVJJIHRvIHBhcnNlXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3Iob3B0X3VyaSA9ICcnKSB7XG5cdFx0dGhpcy51cmwgPSBVcmkucGFyc2UodGhpcy5tYXliZUFkZFByb3RvY29sQW5kSG9zdG5hbWVfKG9wdF91cmkpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHBhcmFtZXRlcnMgdG8gdXJpIGZyb20gYSA8Y29kZT5NdWx0aU1hcDwvY29kZT4gYXMgc291cmNlLlxuXHQgKiBAcGFyYW0ge011bHRpTWFwfSBtdWx0aW1hcCBUaGUgPGNvZGU+TXVsdGlNYXA8L2NvZGU+IGNvbnRhaW5pbmcgdGhlXG5cdCAqICAgcGFyYW1ldGVycy5cblx0ICogQHByb3RlY3RlZFxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRhZGRQYXJhbWV0ZXJzRnJvbU11bHRpTWFwKG11bHRpbWFwKSB7XG5cdFx0bXVsdGltYXAubmFtZXMoKS5mb3JFYWNoKChuYW1lKSA9PiB7XG5cdFx0XHRtdWx0aW1hcC5nZXRBbGwobmFtZSkuZm9yRWFjaCgodmFsdWUpID0+IHtcblx0XHRcdFx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShuYW1lLCB2YWx1ZSk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRoZSB2YWx1ZSBvZiB0aGUgbmFtZWQgcXVlcnkgcGFyYW1ldGVycy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgcGFyYW1ldGVyIHRvIHNldC5cblx0ICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgbmV3IHZhbHVlLiBXaWxsIGJlIGV4cGxpY2l0bHkgY2FzdGVkIHRvIFN0cmluZy5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0aWYgKGlzRGVmKHZhbHVlKSkge1xuXHRcdFx0dmFsdWUgPSBTdHJpbmcodmFsdWUpO1xuXHRcdH1cblx0XHR0aGlzLnF1ZXJ5LmFkZChuYW1lLCB2YWx1ZSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB0aGUgdmFsdWVzIG9mIHRoZSBuYW1lZCBxdWVyeSBwYXJhbWV0ZXIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHBhcmFtZXRlciB0byBzZXQuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkUGFyYW1ldGVyVmFsdWVzKG5hbWUsIHZhbHVlcykge1xuXHRcdHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4gdGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShuYW1lLCB2YWx1ZSkpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEVuc3VyZXMgcXVlcnkgaW50ZXJuYWwgbWFwIGlzIGluaXRpYWxpemVkIGFuZCBzeW5jZWQgd2l0aCBpbml0aWFsIHZhbHVlXG5cdCAqIGV4dHJhY3RlZCBmcm9tIFVSSSBzZWFyY2ggcGFydC5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0ZW5zdXJlUXVlcnlJbml0aWFsaXplZF8oKSB7XG5cdFx0aWYgKHRoaXMucXVlcnkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5xdWVyeSA9IG5ldyBNdWx0aU1hcCgpO1xuXHRcdHZhciBzZWFyY2ggPSB0aGlzLnVybC5zZWFyY2g7XG5cdFx0aWYgKHNlYXJjaCkge1xuXHRcdFx0c2VhcmNoLnN1YnN0cmluZygxKS5zcGxpdCgnJicpLmZvckVhY2goKHBhcmFtKSA9PiB7XG5cdFx0XHRcdHZhciBba2V5LCB2YWx1ZV0gPSBwYXJhbS5zcGxpdCgnPScpO1xuXHRcdFx0XHRpZiAoaXNEZWYodmFsdWUpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBVcmkudXJsRGVjb2RlKHZhbHVlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmFkZFBhcmFtZXRlclZhbHVlKGtleSwgdmFsdWUpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGhhc2ggcGFydCBvZiB1cmkuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldEhhc2goKSB7XG5cdFx0cmV0dXJuIHRoaXMudXJsLmhhc2ggfHwgJyc7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgaG9zdCBwYXJ0IG9mIHVyaS4gRS5nLiA8Y29kZT5baG9zdG5hbWVdOltwb3J0XTwvY29kZT4uXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldEhvc3QoKSB7XG5cdFx0dmFyIGhvc3QgPSB0aGlzLmdldEhvc3RuYW1lKCk7XG5cdFx0aWYgKGhvc3QpIHtcblx0XHRcdHZhciBwb3J0ID0gdGhpcy5nZXRQb3J0KCk7XG5cdFx0XHRpZiAocG9ydCAmJiBwb3J0ICE9PSAnODAnKSB7XG5cdFx0XHRcdGhvc3QgKz0gJzonICsgcG9ydDtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGhvc3Q7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgaG9zdG5hbWUgcGFydCBvZiB1cmkgd2l0aG91dCBwcm90b2NvbCBhbmQgcG9ydC5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0SG9zdG5hbWUoKSB7XG5cdFx0dmFyIGhvc3RuYW1lID0gdGhpcy51cmwuaG9zdG5hbWU7XG5cdFx0aWYgKGhvc3RuYW1lID09PSBVcmkuSE9TVE5BTUVfUExBQ0VIT0xERVIpIHtcblx0XHRcdHJldHVybiAnJztcblx0XHR9XG5cdFx0cmV0dXJuIGhvc3RuYW1lO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIG9yaWdpbiBwYXJ0IG9mIHVyaS4gRS5nLiA8Y29kZT5odHRwOi8vW2hvc3RuYW1lXTpbcG9ydF08L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRPcmlnaW4oKSB7XG5cdFx0dmFyIGhvc3QgPSB0aGlzLmdldEhvc3QoKTtcblx0XHRpZiAoaG9zdCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0UHJvdG9jb2woKSArICcvLycgKyBob3N0O1xuXHRcdH1cblx0XHRyZXR1cm4gJyc7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgZmlyc3QgdmFsdWUgZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyIG9yIHVuZGVmaW5lZCBpZiB0aGUgZ2l2ZW5cblx0ICogcGFyYW1ldGVyIG5hbWUgZG9lcyBub3QgYXBwZWFyIGluIHRoZSBxdWVyeSBzdHJpbmcuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbU5hbWUgVW5lc2NhcGVkIHBhcmFtZXRlciBuYW1lLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBUaGUgZmlyc3QgdmFsdWUgZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyIG9yXG5cdCAqICAgdW5kZWZpbmVkIGlmIHRoZSBnaXZlbiBwYXJhbWV0ZXIgbmFtZSBkb2VzIG5vdCBhcHBlYXIgaW4gdGhlIHF1ZXJ5XG5cdCAqICAgc3RyaW5nLlxuXHQgKi9cblx0Z2V0UGFyYW1ldGVyVmFsdWUobmFtZSkge1xuXHRcdHRoaXMuZW5zdXJlUXVlcnlJbml0aWFsaXplZF8oKTtcblx0XHRyZXR1cm4gdGhpcy5xdWVyeS5nZXQobmFtZSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgdmFsdWU8Yj5zPC9iPiBmb3IgYSBnaXZlbiBwYXJhbWV0ZXIgYXMgYSBsaXN0IG9mIGRlY29kZWRcblx0ICogcXVlcnkgcGFyYW1ldGVyIHZhbHVlcy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIHBhcmFtZXRlciB0byBnZXQgdmFsdWVzIGZvci5cblx0ICogQHJldHVybiB7IUFycmF5PD8+fSBUaGUgdmFsdWVzIGZvciBhIGdpdmVuIHBhcmFtZXRlciBhcyBhIGxpc3Qgb2YgZGVjb2RlZFxuXHQgKiAgIHF1ZXJ5IHBhcmFtZXRlciB2YWx1ZXMuXG5cdCAqL1xuXHRnZXRQYXJhbWV0ZXJWYWx1ZXMobmFtZSkge1xuXHRcdHRoaXMuZW5zdXJlUXVlcnlJbml0aWFsaXplZF8oKTtcblx0XHRyZXR1cm4gdGhpcy5xdWVyeS5nZXRBbGwobmFtZSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgbmFtZTxiPnM8L2I+IG9mIHRoZSBwYXJhbWV0ZXJzLlxuXHQgKiBAcmV0dXJuIHshQXJyYXk8c3RyaW5nPn0gVGhlIG5hbWVzIGZvciB0aGUgcGFyYW1ldGVycyBhcyBhIGxpc3Qgb2Zcblx0ICogICBzdHJpbmdzLlxuXHQgKi9cblx0Z2V0UGFyYW1ldGVyTmFtZXMoKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdHJldHVybiB0aGlzLnF1ZXJ5Lm5hbWVzKCk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZnVuY3Rpb24gY3VycmVudGx5IGJlaW5nIHVzZWQgdG8gcGFyc2UgVVJJcy5cblx0ICogQHJldHVybiB7IWZ1bmN0aW9uKCl9XG5cdCAqL1xuXHRzdGF0aWMgZ2V0UGFyc2VGbigpIHtcblx0XHRyZXR1cm4gcGFyc2VGbl87XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcGF0aG5hbWUgcGFydCBvZiB1cmkuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldFBhdGhuYW1lKCkge1xuXHRcdHJldHVybiB0aGlzLnVybC5wYXRobmFtZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBwb3J0IG51bWJlciBwYXJ0IG9mIHVyaSBhcyBzdHJpbmcuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldFBvcnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMudXJsLnBvcnQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcHJvdG9jb2wgcGFydCBvZiB1cmkuIEUuZy4gPGNvZGU+aHR0cDo8L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRQcm90b2NvbCgpIHtcblx0XHRyZXR1cm4gdGhpcy51cmwucHJvdG9jb2w7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2VhcmNoIHBhcnQgb2YgdXJpLiBTZWFyY2ggdmFsdWUgaXMgcmV0cmlldmVkIGZyb20gcXVlcnlcblx0ICogcGFyYW1ldGVycy5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0U2VhcmNoKCkge1xuXHRcdHZhciBzZWFyY2ggPSAnJztcblx0XHR2YXIgcXVlcnlzdHJpbmcgPSAnJztcblx0XHR0aGlzLmdldFBhcmFtZXRlck5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuXHRcdFx0dGhpcy5nZXRQYXJhbWV0ZXJWYWx1ZXMobmFtZSkuZm9yRWFjaCgodmFsdWUpID0+IHtcblx0XHRcdFx0cXVlcnlzdHJpbmcgKz0gbmFtZTtcblx0XHRcdFx0aWYgKGlzRGVmKHZhbHVlKSkge1xuXHRcdFx0XHRcdHF1ZXJ5c3RyaW5nICs9ICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cXVlcnlzdHJpbmcgKz0gJyYnO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0cXVlcnlzdHJpbmcgPSBxdWVyeXN0cmluZy5zbGljZSgwLCAtMSk7XG5cdFx0aWYgKHF1ZXJ5c3RyaW5nKSB7XG5cdFx0XHRzZWFyY2ggKz0gJz8nICsgcXVlcnlzdHJpbmc7XG5cdFx0fVxuXHRcdHJldHVybiBzZWFyY2g7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHVyaSBjb250YWlucyB0aGUgcGFyYW1ldGVyLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0aGFzUGFyYW1ldGVyKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0cmV0dXJuIHRoaXMucXVlcnkuY29udGFpbnMobmFtZSk7XG5cdH1cblxuXHQvKipcblx0ICogTWFrZXMgdGhpcyBVUkwgdW5pcXVlIGJ5IGFkZGluZyBhIHJhbmRvbSBwYXJhbSB0byBpdC4gVXNlZnVsIGZvciBhdm9pZGluZ1xuXHQgKiBjYWNoZS5cblx0ICovXG5cdG1ha2VVbmlxdWUoKSB7XG5cdFx0dGhpcy5zZXRQYXJhbWV0ZXJWYWx1ZShVcmkuUkFORE9NX1BBUkFNLCBzdHJpbmcuZ2V0UmFuZG9tU3RyaW5nKCkpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIGFkZHMgcHJvdG9jb2wgYW5kIGEgaG9zdG5hbWUgcGxhY2Vob2xkZXIgb24gYSBwYXJpYWwgVVJJIGlmIG5lZWRlZC5cblx0ICogUmVsZXZlbnQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCA8Y29kZT5VUkw8L2NvZGU+IG5hdGl2ZSBvYmplY3QuXG5cdCAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X3VyaVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFVSSSB3aXRoIHByb3RvY29sIGFuZCBob3N0bmFtZSBwbGFjZWhvbGRlci5cblx0ICovXG5cdG1heWJlQWRkUHJvdG9jb2xBbmRIb3N0bmFtZV8ob3B0X3VyaSkge1xuXHRcdHZhciB1cmwgPSBvcHRfdXJpO1xuXHRcdGlmIChvcHRfdXJpLmluZGV4T2YoJzovLycpID09PSAtMSAmJlxuXHRcdFx0b3B0X3VyaS5pbmRleE9mKCdqYXZhc2NyaXB0OicpICE9PSAwKSB7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuXG5cdFx0XHR1cmwgPSBVcmkuREVGQVVMVF9QUk9UT0NPTDtcblx0XHRcdGlmIChvcHRfdXJpWzBdICE9PSAnLycgfHwgb3B0X3VyaVsxXSAhPT0gJy8nKSB7XG5cdFx0XHRcdHVybCArPSAnLy8nO1xuXHRcdFx0fVxuXG5cdFx0XHRzd2l0Y2ggKG9wdF91cmkuY2hhckF0KDApKSB7XG5cdFx0XHRcdGNhc2UgJy4nOlxuXHRcdFx0XHRjYXNlICc/Jzpcblx0XHRcdFx0Y2FzZSAnIyc6XG5cdFx0XHRcdFx0dXJsICs9IFVyaS5IT1NUTkFNRV9QTEFDRUhPTERFUjtcblx0XHRcdFx0XHR1cmwgKz0gJy8nO1xuXHRcdFx0XHRcdHVybCArPSBvcHRfdXJpO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICcnOlxuXHRcdFx0XHRjYXNlICcvJzpcblx0XHRcdFx0XHRpZiAob3B0X3VyaVsxXSAhPT0gJy8nKSB7XG5cdFx0XHRcdFx0XHR1cmwgKz0gVXJpLkhPU1ROQU1FX1BMQUNFSE9MREVSO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR1cmwgKz0gb3B0X3VyaTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHR1cmwgKz0gb3B0X3VyaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHVybDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgdGhlIGdpdmVuIHVyaSBzdHJpbmcgaW50byBhbiBvYmplY3QuXG5cdCAqIEBwYXJhbSB7Kj19IG9wdF91cmkgT3B0aW9uYWwgc3RyaW5nIFVSSSB0byBwYXJzZVxuXHQgKi9cblx0c3RhdGljIHBhcnNlKG9wdF91cmkpIHtcblx0XHRyZXR1cm4gcGFyc2VGbl8ob3B0X3VyaSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgbmFtZWQgcXVlcnkgcGFyYW1ldGVyLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgcGFyYW1ldGVyIHRvIHJlbW92ZS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0cmVtb3ZlUGFyYW1ldGVyKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0dGhpcy5xdWVyeS5yZW1vdmUobmFtZSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB1bmlxdWVuZXNzIHBhcmFtZXRlciBvZiB0aGUgdXJpLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRyZW1vdmVVbmlxdWUoKSB7XG5cdFx0dGhpcy5yZW1vdmVQYXJhbWV0ZXIoVXJpLlJBTkRPTV9QQVJBTSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgaGFzaC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGhhc2hcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0SGFzaChoYXNoKSB7XG5cdFx0dGhpcy51cmwuaGFzaCA9IGhhc2g7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgaG9zdG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBob3N0bmFtZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXRIb3N0bmFtZShob3N0bmFtZSkge1xuXHRcdHRoaXMudXJsLmhvc3RuYW1lID0gaG9zdG5hbWU7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlcnMsIGNsZWFyaW5nIHByZXZpb3VzIHZhbHVlc1xuXHQgKiBmb3IgdGhhdCBrZXkuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHBhcmFtZXRlciB0byBzZXQuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0UGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLnJlbW92ZVBhcmFtZXRlcihuYW1lKTtcblx0XHR0aGlzLmFkZFBhcmFtZXRlclZhbHVlKG5hbWUsIHZhbHVlKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSB2YWx1ZXMgb2YgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlcnMsIGNsZWFyaW5nIHByZXZpb3VzIHZhbHVlc1xuXHQgKiBmb3IgdGhhdCBrZXkuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHBhcmFtZXRlciB0byBzZXQuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0UGFyYW1ldGVyVmFsdWVzKG5hbWUsIHZhbHVlcykge1xuXHRcdHRoaXMucmVtb3ZlUGFyYW1ldGVyKG5hbWUpO1xuXHRcdHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4gdGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShuYW1lLCB2YWx1ZSkpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHBhdGhuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGF0aG5hbWVcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0UGF0aG5hbWUocGF0aG5hbWUpIHtcblx0XHR0aGlzLnVybC5wYXRobmFtZSA9IHBhdGhuYW1lO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHBvcnQgbnVtYmVyLlxuXHQgKiBAcGFyYW0geyp9IHBvcnQgUG9ydCBudW1iZXIuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBvcnQocG9ydCkge1xuXHRcdHRoaXMudXJsLnBvcnQgPSBwb3J0O1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSB1c2VkIGZvciBwYXJzaW5nIHRoZSBvcmlnaW5hbCBzdHJpbmcgdXJpXG5cdCAqIGludG8gYW4gb2JqZWN0LlxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBwYXJzZUZuXG5cdCAqL1xuXHRzdGF0aWMgc2V0UGFyc2VGbihwYXJzZUZuKSB7XG5cdFx0cGFyc2VGbl8gPSBwYXJzZUZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHByb3RvY29sLiBJZiBtaXNzaW5nIDxjb2RlPmh0dHA6PC9jb2RlPiBpcyB1c2VkIGFzIGRlZmF1bHQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwcm90b2NvbFxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXRQcm90b2NvbChwcm90b2NvbCkge1xuXHRcdHRoaXMudXJsLnByb3RvY29sID0gcHJvdG9jb2w7XG5cdFx0aWYgKHRoaXMudXJsLnByb3RvY29sW3RoaXMudXJsLnByb3RvY29sLmxlbmd0aCAtIDFdICE9PSAnOicpIHtcblx0XHRcdHRoaXMudXJsLnByb3RvY29sICs9ICc6Jztcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5nIGZvcm0gb2YgdGhlIHVybC5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHR0b1N0cmluZygpIHtcblx0XHR2YXIgaHJlZiA9ICcnO1xuXHRcdHZhciBob3N0ID0gdGhpcy5nZXRIb3N0KCk7XG5cdFx0aWYgKGhvc3QpIHtcblx0XHRcdGhyZWYgKz0gdGhpcy5nZXRQcm90b2NvbCgpICsgJy8vJztcblx0XHR9XG5cdFx0aHJlZiArPSBob3N0ICsgdGhpcy5nZXRQYXRobmFtZSgpICsgdGhpcy5nZXRTZWFyY2goKSArIHRoaXMuZ2V0SGFzaCgpO1xuXHRcdHJldHVybiBocmVmO1xuXHR9XG5cblx0LyoqXG5cdCAqIEpvaW5zIHRoZSBnaXZlbiBwYXRocy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoXG5cdCAqIEBwYXJhbSB7Li4uc3RyaW5nfSAuLi5wYXRocyBBbnkgbnVtYmVyIG9mIHBhdGhzIHRvIGJlIGpvaW5lZCB3aXRoIHRoZSBiYXNlIHVybC5cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGpvaW5QYXRocyhiYXNlUGF0aCwgLi4ucGF0aHMpIHtcblx0XHRpZiAoYmFzZVBhdGguY2hhckF0KGJhc2VQYXRoLmxlbmd0aCAtIDEpID09PSAnLycpIHtcblx0XHRcdGJhc2VQYXRoID0gYmFzZVBhdGguc3Vic3RyaW5nKDAsIGJhc2VQYXRoLmxlbmd0aCAtIDEpO1xuXHRcdH1cblx0XHRwYXRocyA9IHBhdGhzLm1hcChwYXRoID0+IHBhdGguY2hhckF0KDApID09PSAnLycgPyBwYXRoLnN1YnN0cmluZygxKSA6IHBhdGgpO1xuXHRcdHJldHVybiBbYmFzZVBhdGhdLmNvbmNhdChwYXRocykuam9pbignLycpLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG5cdH1cblxuXHQvKipcblx0ICogVVJMLWRlY29kZXMgdGhlIHN0cmluZy4gV2UgbmVlZCB0byBzcGVjaWFsbHkgaGFuZGxlICcrJ3MgYmVjYXVzZVxuXHQgKiB0aGUgamF2YXNjcmlwdCBsaWJyYXJ5IGRvZXNuJ3QgY29udmVydCB0aGVtIHRvIHNwYWNlcy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0ciBUaGUgc3RyaW5nIHRvIHVybCBkZWNvZGUuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGRlY29kZWQge0Bjb2RlIHN0cn0uXG5cdCAqL1xuXHRzdGF0aWMgdXJsRGVjb2RlKHN0cikge1xuXHRcdHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyLnJlcGxhY2UoL1xcKy9nLCAnICcpKTtcblx0fVxuXG59XG5cbi8qKlxuICogRGVmYXVsdCBwcm90b2NvbCB2YWx1ZS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAZGVmYXVsdCBodHRwOlxuICogQHN0YXRpY1xuICovXG5jb25zdCBpc1NlY3VyZSA9ICgpID0+XG5cdCh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuXHRcdHdpbmRvdy5sb2NhdGlvbiAmJlxuXHRcdHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCAmJlxuXHRcdHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5pbmRleE9mKCdodHRwcycpID09PSAwKTtcblxuVXJpLkRFRkFVTFRfUFJPVE9DT0wgPSBpc1NlY3VyZSgpID8gJ2h0dHBzOicgOiAnaHR0cDonO1xuXG4vKipcbiAqIEhvc3RuYW1lIHBsYWNlaG9sZGVyLiBSZWxldmFudCB0byBpbnRlcm5hbCB1c2FnZSBvbmx5LlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuVXJpLkhPU1ROQU1FX1BMQUNFSE9MREVSID0gJ2hvc3RuYW1lJyArIERhdGUubm93KCk7XG5cbi8qKlxuICogTmFtZSB1c2VkIGJ5IHRoZSBwYXJhbSBnZW5lcmF0ZWQgYnkgYG1ha2VVbmlxdWVgLlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuVXJpLlJBTkRPTV9QQVJBTSA9ICd6eCc7XG5cbmV4cG9ydCBkZWZhdWx0IFVyaTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgZXhpdERvY3VtZW50IH0gZnJvbSAnbWV0YWwtZG9tJztcbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgVXJpIGZyb20gJ21ldGFsLXVyaSc7XG5cbi8qKlxuICogQSBjb2xsZWN0aW9uIG9mIHN0YXRpYyB1dGlsaXR5IGZ1bmN0aW9ucy5cbiAqIEBjb25zdFxuICovXG5jbGFzcyB1dGlscyB7XG5cblx0LyoqXG5cdCAqIENvcGllcyBhdHRyaWJ1dGVzIGZvcm0gc291cmNlIG5vZGUgdG8gdGFyZ2V0IG5vZGUuXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBjb3B5Tm9kZUF0dHJpYnV0ZXMoc291cmNlLCB0YXJnZXQpIHtcblx0XHRBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChzb3VyY2UuYXR0cmlidXRlcykuZm9yRWFjaCgoYXR0cmlidXRlKSA9PiB0YXJnZXQuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZS5uYW1lLCBhdHRyaWJ1dGUudmFsdWUpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBjdXJyZW50IGJyb3dzZXIgcGF0aCBpbmNsdWRpbmcgaGFzaGJhbmcuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXRDdXJyZW50QnJvd3NlclBhdGgoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0Q3VycmVudEJyb3dzZXJQYXRoV2l0aG91dEhhc2goKSArIGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhhc2g7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY3VycmVudCBicm93c2VyIHBhdGggZXhjbHVkaW5nIGhhc2hiYW5nLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0Q3VycmVudEJyb3dzZXJQYXRoV2l0aG91dEhhc2goKSB7XG5cdFx0cmV0dXJuIGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnBhdGhuYW1lICsgZ2xvYmFscy53aW5kb3cubG9jYXRpb24uc2VhcmNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGdpdmVuIG5vZGUgb2Zmc2V0IGNvb3JkaW5hdGVzLlxuXHQgKiBAcmV0dXJuIHshb2JqZWN0fVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0Tm9kZU9mZnNldChub2RlKSB7XG5cdFx0bGV0IFtvZmZzZXRMZWZ0LCBvZmZzZXRUb3BdID0gWzAsIDBdO1xuXHRcdGRvIHtcblx0XHRcdG9mZnNldExlZnQgKz0gbm9kZS5vZmZzZXRMZWZ0O1xuXHRcdFx0b2Zmc2V0VG9wICs9IG5vZGUub2Zmc2V0VG9wO1xuXHRcdFx0bm9kZSA9IG5vZGUub2Zmc2V0UGFyZW50O1xuXHRcdH0gd2hpbGUgKG5vZGUpO1xuXHRcdHJldHVybiB7XG5cdFx0XHRvZmZzZXRMZWZ0LFxuXHRcdFx0b2Zmc2V0VG9wXG5cdFx0fTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyB0aGUgcGF0aCBwYXJ0IG9mIGFuIHVybC5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldFVybFBhdGgodXJsKSB7XG5cdFx0dmFyIHVyaSA9IG5ldyBVcmkodXJsKTtcblx0XHRyZXR1cm4gdXJpLmdldFBhdGhuYW1lKCkgKyB1cmkuZ2V0U2VhcmNoKCkgKyB1cmkuZ2V0SGFzaCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIHRoZSBwYXRoIHBhcnQgb2YgYW4gdXJsIHdpdGhvdXQgaGFzaGJhbmcuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXRVcmxQYXRoV2l0aG91dEhhc2godXJsKSB7XG5cdFx0dmFyIHVyaSA9IG5ldyBVcmkodXJsKTtcblx0XHRyZXR1cm4gdXJpLmdldFBhdGhuYW1lKCkgKyB1cmkuZ2V0U2VhcmNoKCk7XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgdGhlIHBhdGggcGFydCBvZiBhbiB1cmwgd2l0aG91dCBoYXNoYmFuZyBhbmQgcXVlcnkgc2VhcmNoLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0VXJsUGF0aFdpdGhvdXRIYXNoQW5kU2VhcmNoKHVybCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHVybCk7XG5cdFx0cmV0dXJuIHVyaS5nZXRQYXRobmFtZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB1cmwgaXMgaW4gdGhlIHNhbWUgYnJvd3NlciBjdXJyZW50IHVybCBleGNsdWRpbmcgdGhlIGhhc2hiYW5nLlxuXHQgKiBAcGFyYW0gIHshc3RyaW5nfSB1cmxcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGlzQ3VycmVudEJyb3dzZXJQYXRoKHVybCkge1xuXHRcdGlmICh1cmwpIHtcblx0XHRcdGNvbnN0IGN1cnJlbnRCcm93c2VyUGF0aCA9IHRoaXMuZ2V0Q3VycmVudEJyb3dzZXJQYXRoV2l0aG91dEhhc2goKTtcblx0XHRcdC8vIHRoZSBnZXRVcmxQYXRoIHdpbGwgY3JlYXRlIGEgVXJpIGFuZCB3aWxsIG5vcm1hbGl6ZSB0aGUgcGF0aCBhbmRcblx0XHRcdC8vIHJlbW92ZSB0aGUgdHJhaWxsaW5nICcvJyBmb3IgcHJvcGVybHkgY29tcGFyaW5nIHBhdGhzLlxuXHRcdFx0cmV0dXJuIHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaCh1cmwpID09PSB0aGlzLmdldFVybFBhdGgoY3VycmVudEJyb3dzZXJQYXRoKTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdHJ1ZSBpZiBIVE1MNSBIaXN0b3J5IGFwaSBpcyBzdXBwb3J0ZWQuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBpc0h0bWw1SGlzdG9yeVN1cHBvcnRlZCgpIHtcblx0XHRyZXR1cm4gISEoZ2xvYmFscy53aW5kb3cuaGlzdG9yeSAmJiBnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGEgZ2l2ZW4gdXJsIGlzIGEgdmFsaWQgaHR0cChzKSB1cmkgYW5kIHJldHVybnMgdGhlIGZvcm1lZCBVcmlcblx0ICogb3IgZmFsc2UgaWYgdGhlIHBhcnNpbmcgZmFpbGVkXG5cdCAqIEByZXR1cm4ge1VyaXxib29sZWFufVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgaXNXZWJVcmkodXJsKSB7XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBuZXcgVXJpKHVybCk7XG5cdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKGAke2Vyci5tZXNzYWdlfSAke3VybH1gKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBhbGwgYXR0cmlidXRlcyBmb3JtIG5vZGUuXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBjbGVhck5vZGVBdHRyaWJ1dGVzKG5vZGUpIHtcblx0XHRBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChub2RlLmF0dHJpYnV0ZXMpLmZvckVhY2goKGF0dHJpYnV0ZSkgPT4gbm9kZS5yZW1vdmVBdHRyaWJ1dGUoYXR0cmlidXRlLm5hbWUpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgZG9jdW1lbnQuXG5cdCAqIEBwYXJhbSB7IUFycmF5PEVsZW1lbnQ+fSBlbGVtZW50c1xuXHQgKi9cblx0c3RhdGljIHJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50KGVsZW1lbnRzKSB7XG5cdFx0ZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4gZXhpdERvY3VtZW50KGVsZW1lbnQpKTtcblx0fVxuXG5cdC8qKlxuXHQqIFJlbW92ZXMgdHJhaWxpbmcgc2xhc2ggaW4gcGF0aC5cblx0KiBAcGFyYW0geyFzdHJpbmd9XG5cdCogQHJldHVybiB7c3RyaW5nfVxuXHQqL1xuXHRzdGF0aWMgcmVtb3ZlUGF0aFRyYWlsaW5nU2xhc2gocGF0aCkge1xuXHRcdHZhciBsZW5ndGggPSBwYXRoID8gcGF0aC5sZW5ndGggOiAwO1xuXHRcdGlmIChsZW5ndGggPiAxICYmIHBhdGhbbGVuZ3RoIC0gMV0gPT09ICcvJykge1xuXHRcdFx0cGF0aCA9IHBhdGguc3Vic3RyKDAsIGxlbmd0aCAtIDEpO1xuXHRcdH1cblx0XHRyZXR1cm4gcGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgcmFuZG9tIHN1ZmZpeCB0byB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgdGhlIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IWVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHJldHVybiB7ZWxlbWVudH1cblx0ICovXG5cdHN0YXRpYyBzZXRFbGVtZW50V2l0aFJhbmRvbUhyZWYoZWxlbWVudCkge1xuXHRcdGVsZW1lbnQuaHJlZiA9IGVsZW1lbnQuaHJlZiArICc/cT0nICsgTWF0aC5yYW5kb20oKTtcblx0XHRyZXR1cm4gZWxlbWVudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBPdmVycmlkZXMgZG9jdW1lbnQgcmVmZXJyZXJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHJlZmVycmVyXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBzZXRSZWZlcnJlcihyZWZlcnJlcikge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxzLmRvY3VtZW50LCAncmVmZXJyZXInLCB7XG5cdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gcmVmZXJyZXI7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgdXRpbHM7XG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblx0YmFzZVBhdGg6ICdkYXRhLXNlbm5hLWJhc2UtcGF0aCcsXG5cdGxpbmtTZWxlY3RvcjogJ2RhdGEtc2VubmEtbGluay1zZWxlY3RvcicsXG5cdGxvYWRpbmdDc3NDbGFzczogJ2RhdGEtc2VubmEtbG9hZGluZy1jc3MtY2xhc3MnLFxuXHRzZW5uYTogJ2RhdGEtc2VubmEnLFxuXHRkaXNwYXRjaDogJ2RhdGEtc2VubmEtZGlzcGF0Y2gnLFxuXHRzdXJmYWNlOiAnZGF0YS1zZW5uYS1zdXJmYWNlJyxcblx0dXBkYXRlU2Nyb2xsUG9zaXRpb246ICdkYXRhLXNlbm5hLXVwZGF0ZS1zY3JvbGwtcG9zaXRpb24nXG59OyIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtEaXNwb3NhYmxlfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogRXZlbnRIYW5kbGUgdXRpbGl0eS4gSG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgYW4gZXZlbnQgc3Vic2NyaXB0aW9uLCBhbmRcbiAqIGFsbG93cyByZW1vdmluZyB0aGVtIGVhc2lseS5cbiAqIEV2ZW50SGFuZGxlIGlzIGEgRGlzcG9zYWJsZSwgYnV0IGl0J3MgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCB0aGVcbiAqIEV2ZW50RW1pdHRlciB0aGF0IGNyZWF0ZWQgaXQgaXMgbm90IHRoZSBvbmUgcmVzcG9uc2libGUgZm9yIGRpc3Bvc2luZyBpdC5cbiAqIFRoYXQgcmVzcG9uc2liaWxpdHkgaXMgZm9yIHRoZSBjb2RlIHRoYXQgaG9sZHMgYSByZWZlcmVuY2UgdG8gaXQuXG4gKiBAZXh0ZW5kcyB7RGlzcG9zYWJsZX1cbiAqL1xuY2xhc3MgRXZlbnRIYW5kbGUgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIEV2ZW50SGFuZGxlIGNvbnN0cnVjdG9yXG5cdCAqIEBwYXJhbSB7IUV2ZW50RW1pdHRlcn0gZW1pdHRlciBFbWl0dGVyIHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHQgKi9cblx0Y29uc3RydWN0b3IoZW1pdHRlciwgZXZlbnQsIGxpc3RlbmVyKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBFdmVudEVtaXR0ZXIgaW5zdGFuY2UgdGhhdCB0aGUgZXZlbnQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5lbWl0dGVyXyA9IGVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdGhhdCB3YXMgc3Vic2NyaWJlZCB0by5cblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmV2ZW50XyA9IGV2ZW50O1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHRcdCAqIEB0eXBlIHtGdW5jdGlvbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5saXN0ZW5lcl8gPSBsaXN0ZW5lcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBvZiB0aGlzIGluc3RhbmNlJ3Mgb2JqZWN0IHJlZmVyZW5jZXMuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR0aGlzLmVtaXR0ZXJfID0gbnVsbDtcblx0XHR0aGlzLmxpc3RlbmVyXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgc3Vic2NyaXB0aW9uIGZyb20gdGhlIGVtaXR0ZXIuXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHRpZiAoIXRoaXMuZW1pdHRlcl8uaXNEaXNwb3NlZCgpKSB7XG5cdFx0XHR0aGlzLmVtaXR0ZXJfLnJlbW92ZUxpc3RlbmVyKHRoaXMuZXZlbnRfLCB0aGlzLmxpc3RlbmVyXyk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50SGFuZGxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2FycmF5LCBEaXNwb3NhYmxlLCBpc0Z1bmN0aW9uLCBpc1N0cmluZ30gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IEV2ZW50SGFuZGxlIGZyb20gJy4vRXZlbnRIYW5kbGUnO1xuXG5jb25zdCBzaW5nbGVBcnJheV8gPSBbMF07XG5cbi8qKlxuICogRXZlbnRFbWl0dGVyIHV0aWxpdHkuXG4gKiBAZXh0ZW5kcyB7RGlzcG9zYWJsZX1cbiAqL1xuY2xhc3MgRXZlbnRFbWl0dGVyIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBFdmVudEVtaXR0ZXIgY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBldmVudCBsaXN0ZW5lcnMgc2NvcGVkIGJ5IGV2ZW50IHR5cGUuXG5cdFx0ICogQHR5cGUge09iamVjdDxzdHJpbmcsICFBcnJheTwhZnVuY3Rpb24oKT4+fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmV2ZW50c18gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSGFuZGxlcnMgdGhhdCBhcmUgdHJpZ2dlcmVkIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8uXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqL1xuXHRcdHRoaXMubGlzdGVuZXJIYW5kbGVyc18gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogQ29uZmlndXJhdGlvbiBvcHRpb24gd2hpY2ggZGV0ZXJtaW5lcyBpZiBhbiBldmVudCBmYWNhZGUgc2hvdWxkIGJlIHNlbnRcblx0XHQgKiBhcyBhIHBhcmFtIG9mIGxpc3RlbmVycyB3aGVuIGVtaXR0aW5nIGV2ZW50cy4gSWYgc2V0IHRvIHRydWUsIHRoZSBmYWNhZGVcblx0XHQgKiB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnNob3VsZFVzZUZhY2FkZV8gPSBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgaGFuZGxlciB0byBnaXZlbiBob2xkZXIgdmFyaWFibGUuIElmIHRoZSBob2xkZXIgZG9lc24ndCBoYXZlIGFcblx0ICogdmFsdWUgeWV0LCBpdCB3aWxsIHJlY2VpdmUgdGhlIGhhbmRsZXIgZGlyZWN0bHkuIElmIHRoZSBob2xkZXIgaXMgYW4gYXJyYXksXG5cdCAqIHRoZSB2YWx1ZSB3aWxsIGp1c3QgYmUgYWRkZWQgdG8gaXQuIE90aGVyd2lzZSwgdGhlIGhvbGRlciB3aWxsIGJlIHNldCB0byBhXG5cdCAqIG5ldyBhcnJheSBjb250YWluaW5nIGl0cyBwcmV2aW91cyB2YWx1ZSBwbHVzIHRoZSBuZXcgaGFuZGxlci5cblx0ICogQHBhcmFtIHsqfSBob2xkZXJcblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKXxPYmplY3R9IGhhbmRsZXJcblx0ICogQHJldHVybiB7Kn0gVGhlIGhvbGRlcidzIG5ldyB2YWx1ZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkSGFuZGxlcl8oaG9sZGVyLCBoYW5kbGVyKSB7XG5cdFx0aWYgKCFob2xkZXIpIHtcblx0XHRcdGhvbGRlciA9IGhhbmRsZXI7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICghQXJyYXkuaXNBcnJheShob2xkZXIpKSB7XG5cdFx0XHRcdGhvbGRlciA9IFtob2xkZXJdO1xuXHRcdFx0fVxuXHRcdFx0aG9sZGVyLnB1c2goaGFuZGxlcik7XG5cdFx0fVxuXHRcdHJldHVybiBob2xkZXI7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3RlbmVycyBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudHMuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudFxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHBhcmFtIHtib29sZWFufSBkZWZhdWx0TGlzdGVuZXIgRmxhZyBpbmRpY2F0aW5nIGlmIHRoaXMgbGlzdGVuZXIgaXMgYSBkZWZhdWx0XG5cdCAqICAgYWN0aW9uIGZvciB0aGlzIGV2ZW50LiBEZWZhdWx0IGFjdGlvbnMgYXJlIHJ1biBsYXN0LCBhbmQgb25seSBpZiBubyBwcmV2aW91c1xuXHQgKiAgIGxpc3RlbmVyIGNhbGwgYHByZXZlbnREZWZhdWx0KClgIG9uIHRoZSByZWNlaXZlZCBldmVudCBmYWNhZGUuXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cblx0ICovXG5cdGFkZExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lciwgZGVmYXVsdExpc3RlbmVyKSB7XG5cdFx0dGhpcy52YWxpZGF0ZUxpc3RlbmVyXyhsaXN0ZW5lcik7XG5cblx0XHRjb25zdCBldmVudHMgPSB0aGlzLnRvRXZlbnRzQXJyYXlfKGV2ZW50KTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5hZGRTaW5nbGVMaXN0ZW5lcl8oZXZlbnRzW2ldLCBsaXN0ZW5lciwgZGVmYXVsdExpc3RlbmVyKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbmV3IEV2ZW50SGFuZGxlKHRoaXMsIGV2ZW50LCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3RlbmVycyBhcnJheSBmb3IgYSBzaW5nbGUgZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHBhcmFtIHtib29sZWFufSBkZWZhdWx0TGlzdGVuZXIgRmxhZyBpbmRpY2F0aW5nIGlmIHRoaXMgbGlzdGVuZXIgaXMgYSBkZWZhdWx0XG5cdCAqICAgYWN0aW9uIGZvciB0aGlzIGV2ZW50LiBEZWZhdWx0IGFjdGlvbnMgYXJlIHJ1biBsYXN0LCBhbmQgb25seSBpZiBubyBwcmV2aW91c1xuXHQgKiAgIGxpc3RlbmVyIGNhbGwgYHByZXZlbnREZWZhdWx0KClgIG9uIHRoZSByZWNlaXZlZCBldmVudCBmYWNhZGUuXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb249fSBvcmlnaW4gVGhlIG9yaWdpbmFsIGZ1bmN0aW9uIHRoYXQgd2FzIGFkZGVkIGFzIGFcblx0ICogICBsaXN0ZW5lciwgaWYgdGhlcmUgaXMgYW55LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRhZGRTaW5nbGVMaXN0ZW5lcl8oZXZlbnQsIGxpc3RlbmVyLCBkZWZhdWx0TGlzdGVuZXIsIG9yaWdpbikge1xuXHRcdHRoaXMucnVuTGlzdGVuZXJIYW5kbGVyc18oZXZlbnQpO1xuXHRcdGlmIChkZWZhdWx0TGlzdGVuZXIgfHwgb3JpZ2luKSB7XG5cdFx0XHRsaXN0ZW5lciA9IHtcblx0XHRcdFx0ZGVmYXVsdDogZGVmYXVsdExpc3RlbmVyLFxuXHRcdFx0XHRmbjogbGlzdGVuZXIsXG5cdFx0XHRcdG9yaWdpbjogb3JpZ2luLFxuXHRcdFx0fTtcblx0XHR9XG5cdFx0dGhpcy5ldmVudHNfID0gdGhpcy5ldmVudHNfIHx8IHt9O1xuXHRcdHRoaXMuZXZlbnRzX1tldmVudF0gPSB0aGlzLmFkZEhhbmRsZXJfKHRoaXMuZXZlbnRzX1tldmVudF0sIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBCdWlsZHMgZmFjYWRlIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtPYmplY3R9XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGJ1aWxkRmFjYWRlXyhldmVudCkge1xuXHRcdGlmICh0aGlzLmdldFNob3VsZFVzZUZhY2FkZSgpKSB7XG5cdFx0XHRjb25zdCBmYWNhZGUgPSB7XG5cdFx0XHRcdHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRmYWNhZGUucHJldmVudGVkRGVmYXVsdCA9IHRydWU7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRhcmdldDogdGhpcyxcblx0XHRcdFx0dHlwZTogZXZlbnQsXG5cdFx0XHR9O1xuXHRcdFx0cmV0dXJuIGZhY2FkZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLmV2ZW50c18gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4ZWN1dGUgZWFjaCBvZiB0aGUgbGlzdGVuZXJzIGluIG9yZGVyIHdpdGggdGhlIHN1cHBsaWVkIGFyZ3VtZW50cy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7Kn0gb3B0X2FyZ3MgW2FyZzFdLCBbYXJnMl0sIFsuLi5dXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFJldHVybnMgdHJ1ZSBpZiBldmVudCBoYWQgbGlzdGVuZXJzLCBmYWxzZSBvdGhlcndpc2UuXG5cdCAqL1xuXHRlbWl0KGV2ZW50KSB7XG5cdFx0Y29uc3QgbGlzdGVuZXJzID0gdGhpcy5nZXRSYXdMaXN0ZW5lcnNfKGV2ZW50KTtcblx0XHRpZiAobGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGNvbnN0IGFyZ3MgPSBhcnJheS5zbGljZShhcmd1bWVudHMsIDEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0dGhpcy5ydW5MaXN0ZW5lcnNfKGxpc3RlbmVycywgYXJncywgdGhpcy5idWlsZEZhY2FkZV8oZXZlbnQpKTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBsaXN0ZW5lciBvYmplY3RzIGZvciB0aGUgZ2l2ZW4gZXZlbnQsIGlmIHRoZXJlIGFyZSBhbnkuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHshQXJyYXl9XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGdldFJhd0xpc3RlbmVyc18oZXZlbnQpIHtcblx0XHRjb25zdCBkaXJlY3RMaXN0ZW5lcnMgPSB0b0FycmF5KHRoaXMuZXZlbnRzXyAmJiB0aGlzLmV2ZW50c19bZXZlbnRdKTtcblx0XHRyZXR1cm4gZGlyZWN0TGlzdGVuZXJzLmNvbmNhdChcblx0XHRcdHRvQXJyYXkodGhpcy5ldmVudHNfICYmIHRoaXMuZXZlbnRzX1snKiddKVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY29uZmlndXJhdGlvbiBvcHRpb24gd2hpY2ggZGV0ZXJtaW5lcyBpZiBhbiBldmVudCBmYWNhZGUgc2hvdWxkXG5cdCAqIGJlIHNlbnQgYXMgYSBwYXJhbSBvZiBsaXN0ZW5lcnMgd2hlbiBlbWl0dGluZyBldmVudHMuIElmIHNldCB0byB0cnVlLCB0aGVcblx0ICogZmFjYWRlIHdpbGwgYmUgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCBvZiB0aGUgbGlzdGVuZXIuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRnZXRTaG91bGRVc2VGYWNhZGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2hvdWxkVXNlRmFjYWRlXztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge0FycmF5fSBBcnJheSBvZiBsaXN0ZW5lcnMuXG5cdCAqL1xuXHRsaXN0ZW5lcnMoZXZlbnQpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRSYXdMaXN0ZW5lcnNfKGV2ZW50KS5tYXAoXG5cdFx0XHRsaXN0ZW5lciA9PiAobGlzdGVuZXIuZm4gPyBsaXN0ZW5lci5mbiA6IGxpc3RlbmVyKVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgZml4ZWQgbnVtYmVyIG9mIHRpbWVzIGZvciB0aGVcblx0ICogZXZlbnRzLiBBZnRlciBlYWNoIGV2ZW50IGlzIHRyaWdnZXJlZCB0aGUgc3BlY2lmaWVkIGFtb3VudCBvZiB0aW1lcywgdGhlXG5cdCAqIGxpc3RlbmVyIGlzIHJlbW92ZWQgZm9yIGl0LlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudCBUaGUgYW1vdW50IG9mIHRpbWVzIHRoaXMgZXZlbnQgc2hvdWxkIGJlIGxpc3RlbmVkXG5cdCAqIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0bWFueShldmVudCwgYW1vdW50LCBsaXN0ZW5lcikge1xuXHRcdGNvbnN0IGV2ZW50cyA9IHRoaXMudG9FdmVudHNBcnJheV8oZXZlbnQpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLm1hbnlfKGV2ZW50c1tpXSwgYW1vdW50LCBsaXN0ZW5lcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBFdmVudEhhbmRsZSh0aGlzLCBldmVudCwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIGZpeGVkIG51bWJlciBvZiB0aW1lcyBmb3IgYSBzaW5nbGVcblx0ICogZXZlbnQuIEFmdGVyIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQgdGhlIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZXMsIHRoZVxuXHQgKiBsaXN0ZW5lciBpcyByZW1vdmVkLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudCBUaGUgYW1vdW50IG9mIHRpbWVzIHRoaXMgZXZlbnQgc2hvdWxkIGJlIGxpc3RlbmVkXG5cdCAqIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0bWFueV8oZXZlbnQsIGFtb3VudCwgbGlzdGVuZXIpIHtcblx0XHRjb25zdCBzZWxmID0gdGhpcztcblxuXHRcdGlmIChhbW91bnQgPD0gMCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqXG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gaGFuZGxlckludGVybmFsKCkge1xuXHRcdFx0aWYgKC0tYW1vdW50ID09PSAwKSB7XG5cdFx0XHRcdHNlbGYucmVtb3ZlTGlzdGVuZXIoZXZlbnQsIGhhbmRsZXJJbnRlcm5hbCk7XG5cdFx0XHR9XG5cdFx0XHRsaXN0ZW5lci5hcHBseShzZWxmLCBhcmd1bWVudHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0fVxuXG5cdFx0c2VsZi5hZGRTaW5nbGVMaXN0ZW5lcl8oZXZlbnQsIGhhbmRsZXJJbnRlcm5hbCwgZmFsc2UsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgYSBsaXN0ZW5lciBvYmplY3QgbWF0Y2hlcyB0aGUgZ2l2ZW4gbGlzdGVuZXIgZnVuY3Rpb24uIFRvIG1hdGNoLFxuXHQgKiBpdCBuZWVkcyB0byBlaXRoZXIgcG9pbnQgdG8gdGhhdCBsaXN0ZW5lciBvciBoYXZlIGl0IGFzIGl0cyBvcmlnaW4uXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gbGlzdGVuZXJPYmpcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG1hdGNoZXNMaXN0ZW5lcl8obGlzdGVuZXJPYmosIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3QgZm4gPSBsaXN0ZW5lck9iai5mbiB8fCBsaXN0ZW5lck9iajtcblx0XHRyZXR1cm4gKFxuXHRcdFx0Zm4gPT09IGxpc3RlbmVyIHx8XG5cdFx0XHQobGlzdGVuZXJPYmoub3JpZ2luICYmIGxpc3RlbmVyT2JqLm9yaWdpbiA9PT0gbGlzdGVuZXIpIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYSBsaXN0ZW5lciBmb3IgdGhlIHNwZWNpZmllZCBldmVudHMuXG5cdCAqIENhdXRpb246IGNoYW5nZXMgYXJyYXkgaW5kaWNlcyBpbiB0aGUgbGlzdGVuZXIgYXJyYXkgYmVoaW5kIHRoZSBsaXN0ZW5lci5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50XG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fSBSZXR1cm5zIGVtaXR0ZXIsIHNvIGNhbGxzIGNhbiBiZSBjaGFpbmVkLlxuXHQgKi9cblx0b2ZmKGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHRoaXMudmFsaWRhdGVMaXN0ZW5lcl8obGlzdGVuZXIpO1xuXHRcdGlmICghdGhpcy5ldmVudHNfKSB7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHRjb25zdCBldmVudHMgPSB0aGlzLnRvRXZlbnRzQXJyYXlfKGV2ZW50KTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5ldmVudHNfW2V2ZW50c1tpXV0gPSB0aGlzLnJlbW92ZU1hdGNoaW5nTGlzdGVuZXJPYmpzXyhcblx0XHRcdFx0dG9BcnJheSh0aGlzLmV2ZW50c19bZXZlbnRzW2ldXSksXG5cdFx0XHRcdGxpc3RlbmVyXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRzXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG5cdCAqL1xuXHRvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5hZGRMaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBoYW5kbGVyIHRoYXQgZ2V0cyB0cmlnZ2VyZWQgd2hlbiBhbiBldmVudCBpcyBsaXN0ZW5lZCB0byBvbiB0aGlzXG5cdCAqIGluc3RhbmNlLlxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBoYW5kbGVyXG5cdCAqL1xuXHRvbkxpc3RlbmVyKGhhbmRsZXIpIHtcblx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfID0gdGhpcy5hZGRIYW5kbGVyXyhcblx0XHRcdHRoaXMubGlzdGVuZXJIYW5kbGVyc18sXG5cdFx0XHRoYW5kbGVyXG5cdFx0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBvbmUgdGltZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50cy4gVGhpcyBsaXN0ZW5lciBpcyBpbnZva2VkIG9ubHkgdGhlXG5cdCAqIG5leHQgdGltZSBlYWNoIGV2ZW50IGlzIGZpcmVkLCBhZnRlciB3aGljaCBpdCBpcyByZW1vdmVkLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRzXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG5cdCAqL1xuXHRvbmNlKGV2ZW50cywgbGlzdGVuZXIpIHtcblx0XHRyZXR1cm4gdGhpcy5tYW55KGV2ZW50cywgMSwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycywgb3IgdGhvc2Ugb2YgdGhlIHNwZWNpZmllZCBldmVudHMuIEl0J3Mgbm90IGEgZ29vZFxuXHQgKiBpZGVhIHRvIHJlbW92ZSBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkIGVsc2V3aGVyZSBpbiB0aGUgY29kZSxcblx0ICogZXNwZWNpYWxseSB3aGVuIGl0J3Mgb24gYW4gZW1pdHRlciB0aGF0IHlvdSBkaWRuJ3QgY3JlYXRlLlxuXHQgKiBAcGFyYW0geyhBcnJheXxzdHJpbmcpPX0gZXZlbnRcblx0ICogQHJldHVybiB7IU9iamVjdH0gUmV0dXJucyBlbWl0dGVyLCBzbyBjYWxscyBjYW4gYmUgY2hhaW5lZC5cblx0ICovXG5cdHJlbW92ZUFsbExpc3RlbmVycyhldmVudCkge1xuXHRcdGlmICh0aGlzLmV2ZW50c18pIHtcblx0XHRcdGlmIChldmVudCkge1xuXHRcdFx0XHRjb25zdCBldmVudHMgPSB0aGlzLnRvRXZlbnRzQXJyYXlfKGV2ZW50KTtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHR0aGlzLmV2ZW50c19bZXZlbnRzW2ldXSA9IG51bGw7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuZXZlbnRzXyA9IG51bGw7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGxpc3RlbmVyIG9iamVjdHMgZnJvbSB0aGUgZ2l2ZW4gYXJyYXkgdGhhdCBtYXRjaCB0aGUgZ2l2ZW5cblx0ICogbGlzdGVuZXIgZnVuY3Rpb24uXG5cdCAqIEBwYXJhbSB7QXJyYXkuPE9iamVjdD59IGxpc3RlbmVyT2Jqc1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7QXJyYXkuPE9iamVjdD58T2JqZWN0fSBUaGUgbmV3IGxpc3RlbmVycyBhcnJheSBmb3IgdGhpcyBldmVudC5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0cmVtb3ZlTWF0Y2hpbmdMaXN0ZW5lck9ianNfKGxpc3RlbmVyT2JqcywgbGlzdGVuZXIpIHtcblx0XHRjb25zdCBmaW5hbExpc3RlbmVycyA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJPYmpzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoIXRoaXMubWF0Y2hlc0xpc3RlbmVyXyhsaXN0ZW5lck9ianNbaV0sIGxpc3RlbmVyKSkge1xuXHRcdFx0XHRmaW5hbExpc3RlbmVycy5wdXNoKGxpc3RlbmVyT2Jqc1tpXSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmaW5hbExpc3RlbmVycy5sZW5ndGggPiAwID8gZmluYWxMaXN0ZW5lcnMgOiBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYSBsaXN0ZW5lciBmb3IgdGhlIHNwZWNpZmllZCBldmVudHMuXG5cdCAqIENhdXRpb246IGNoYW5nZXMgYXJyYXkgaW5kaWNlcyBpbiB0aGUgbGlzdGVuZXIgYXJyYXkgYmVoaW5kIHRoZSBsaXN0ZW5lci5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IU9iamVjdH0gUmV0dXJucyBlbWl0dGVyLCBzbyBjYWxscyBjYW4gYmUgY2hhaW5lZC5cblx0ICovXG5cdHJlbW92ZUxpc3RlbmVyKCkge1xuXHRcdHJldHVybiB0aGlzLm9mZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdH1cblxuXHQvKipcblx0ICogUnVucyB0aGUgaGFuZGxlcnMgd2hlbiBhbiBldmVudCBpcyBsaXN0ZW5lZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJ1bkxpc3RlbmVySGFuZGxlcnNfKGV2ZW50KSB7XG5cdFx0bGV0IGhhbmRsZXJzID0gdGhpcy5saXN0ZW5lckhhbmRsZXJzXztcblx0XHRpZiAoaGFuZGxlcnMpIHtcblx0XHRcdGhhbmRsZXJzID0gdG9BcnJheShoYW5kbGVycyk7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGhhbmRsZXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGhhbmRsZXJzW2ldKGV2ZW50KTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUnVucyB0aGUgZ2l2ZW4gbGlzdGVuZXJzLlxuXHQgKiBAcGFyYW0geyFBcnJheX0gbGlzdGVuZXJzXG5cdCAqIEBwYXJhbSB7IUFycmF5fSBhcmdzXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBmYWNhZGVcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0cnVuTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGFyZ3MsIGZhY2FkZSkge1xuXHRcdGlmIChmYWNhZGUpIHtcblx0XHRcdGFyZ3MucHVzaChmYWNhZGUpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGRlZmF1bHRMaXN0ZW5lcnMgPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV0uZm4gfHwgbGlzdGVuZXJzW2ldO1xuXHRcdFx0aWYgKGxpc3RlbmVyc1tpXS5kZWZhdWx0KSB7XG5cdFx0XHRcdGRlZmF1bHRMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmdzKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKCFmYWNhZGUgfHwgIWZhY2FkZS5wcmV2ZW50ZWREZWZhdWx0KSB7XG5cdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IGRlZmF1bHRMaXN0ZW5lcnMubGVuZ3RoOyBqKyspIHtcblx0XHRcdFx0ZGVmYXVsdExpc3RlbmVyc1tqXS5hcHBseSh0aGlzLCBhcmdzKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgY29uZmlndXJhdGlvbiBvcHRpb24gd2hpY2ggZGV0ZXJtaW5lcyBpZiBhbiBldmVudCBmYWNhZGUgc2hvdWxkXG5cdCAqIGJlIHNlbnQgYXMgYSBwYXJhbSBvZiBsaXN0ZW5lcnMgd2hlbiBlbWl0dGluZyBldmVudHMuIElmIHNldCB0byB0cnVlLCB0aGVcblx0ICogZmFjYWRlIHdpbGwgYmUgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCBvZiB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gc2hvdWxkVXNlRmFjYWRlXG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRzZXRTaG91bGRVc2VGYWNhZGUoc2hvdWxkVXNlRmFjYWRlKSB7XG5cdFx0dGhpcy5zaG91bGRVc2VGYWNhZGVfID0gc2hvdWxkVXNlRmFjYWRlO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIHRoZSBwYXJhbWV0ZXIgdG8gYW4gYXJyYXkgaWYgb25seSBvbmUgZXZlbnQgaXMgZ2l2ZW4uIFJldXNlcyB0aGVcblx0ICogc2FtZSBhcnJheSBlYWNoIHRpbWUgdGhpcyBjb252ZXJzaW9uIGlzIGRvbmUsIHRvIGF2b2lkIHVzaW5nIG1vcmUgbWVtb3J5XG5cdCAqIHRoYW4gbmVjZXNzYXJ5LlxuXHQgKiBAcGFyYW0gIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcmV0dXJuIHshQXJyYXl9XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHRvRXZlbnRzQXJyYXlfKGV2ZW50cykge1xuXHRcdGlmIChpc1N0cmluZyhldmVudHMpKSB7XG5cdFx0XHRzaW5nbGVBcnJheV9bMF0gPSBldmVudHM7XG5cdFx0XHRldmVudHMgPSBzaW5nbGVBcnJheV87XG5cdFx0fVxuXHRcdHJldHVybiBldmVudHM7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBsaXN0ZW5lciBpcyB2YWxpZCwgdGhyb3dpbmcgYW4gZXhjZXB0aW9uIHdoZW4gaXQncyBub3QuXG5cdCAqIEBwYXJhbSAgeyp9IGxpc3RlbmVyXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHZhbGlkYXRlTGlzdGVuZXJfKGxpc3RlbmVyKSB7XG5cdFx0aWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignTGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogQ29udmVydHMgdG8gYW4gYXJyYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWxcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiB0b0FycmF5KHZhbCkge1xuXHR2YWwgPSB2YWwgfHwgW107XG5cdHJldHVybiBBcnJheS5pc0FycmF5KHZhbCkgPyB2YWwgOiBbdmFsXTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRFbWl0dGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge0Rpc3Bvc2FibGV9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBFdmVudEVtaXR0ZXJQcm94eSB1dGlsaXR5LiBJdCdzIHJlc3BvbnNpYmxlIGZvciBsaW5raW5nIHR3byBFdmVudEVtaXR0ZXJcbiAqIGluc3RhbmNlcyB0b2dldGhlciwgZW1pdHRpbmcgZXZlbnRzIGZyb20gdGhlIGZpcnN0IGVtaXR0ZXIgdGhyb3VnaCB0aGVcbiAqIHNlY29uZCBvbmUuIFRoYXQgbWVhbnMgdGhhdCBsaXN0ZW5pbmcgdG8gYSBzdXBwb3J0ZWQgZXZlbnQgb24gdGhlIHRhcmdldFxuICogZW1pdHRlciB3aWxsIG1lYW4gbGlzdGVuaW5nIHRvIGl0IG9uIHRoZSBvcmlnaW4gZW1pdHRlciBhcyB3ZWxsLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50RW1pdHRlclByb3h5IGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBAcGFyYW0ge0V2ZW50RW1pdHRlcn0gb3JpZ2luRW1pdHRlciBFdmVudHMgb3JpZ2luYXRlZCBvbiB0aGlzIGVtaXR0ZXJcblx0ICogd2lsbCBiZSBmaXJlZCBmb3IgdGhlIHRhcmdldCBlbWl0dGVyJ3MgbGlzdGVuZXJzIGFzIHdlbGwuXG5cdCAqIEBwYXJhbSB7RXZlbnRFbWl0dGVyfSB0YXJnZXRFbWl0dGVyIEV2ZW50IGxpc3RlbmVycyBhdHRhY2hlZCB0byB0aGlzIGVtaXR0ZXJcblx0ICogd2lsbCBhbHNvIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSBldmVudCBpcyBmaXJlZCBieSB0aGUgb3JpZ2luIGVtaXR0ZXIuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBibGFja2xpc3QgT3B0aW9uYWwgYmxhY2tsaXN0IG9mIGV2ZW50cyB0aGF0IHNob3VsZCBub3QgYmVcblx0ICogcHJveGllZC5cblx0ICogQHBhcmFtIHtPYmplY3R9IHdoaXRlbGlzdFxuXHQgKi9cblx0Y29uc3RydWN0b3Iob3JpZ2luRW1pdHRlciwgdGFyZ2V0RW1pdHRlciwgYmxhY2tsaXN0LCB3aGl0ZWxpc3QpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogTWFwIG9mIGV2ZW50cyB0aGF0IHNob3VsZCBub3QgYmUgcHJveGllZC5cblx0XHQgKiBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmJsYWNrbGlzdF8gPSBibGFja2xpc3Q7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgb3JpZ2luIGVtaXR0ZXIuIFRoaXMgZW1pdHRlcidzIGV2ZW50cyB3aWxsIGJlIHByb3hpZWQgdGhyb3VnaCB0aGVcblx0XHQgKiB0YXJnZXQgZW1pdHRlci5cblx0XHQgKiBAdHlwZSB7RXZlbnRFbWl0dGVyfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfID0gb3JpZ2luRW1pdHRlcjtcblxuXHRcdC8qKlxuXHRcdCAqIEEgbGlzdCBvZiBldmVudHMgdGhhdCBhcmUgcGVuZGluZyB0byBiZSBsaXN0ZW5lZCBieSBhbiBhY3R1YWwgb3JpZ2luXG5cdFx0ICogZW1pdHRlci4gRXZlbnRzIGFyZSBzdG9yZWQgaGVyZSB3aGVuIHRoZSBvcmlnaW4gZG9lc24ndCBleGlzdCwgc28gdGhleVxuXHRcdCAqIGNhbiBiZSBzZXQgb24gYSBuZXcgb3JpZ2luIHdoZW4gb25lIGlzIHNldC5cblx0XHQgKiBAdHlwZSB7QXJyYXl9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucGVuZGluZ0V2ZW50c18gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgYSBtYXAgb2YgZXZlbnRzIGZyb20gdGhlIG9yaWdpbiBlbWl0dGVyIHRoYXQgYXJlIGFscmVhZHkgYmVpbmcgcHJveGllZC5cblx0XHQgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgIUV2ZW50SGFuZGxlPn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5wcm94aWVkRXZlbnRzXyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgdGFyZ2V0IGVtaXR0ZXIuIFRoaXMgZW1pdHRlciB3aWxsIGVtaXQgYWxsIGV2ZW50cyB0aGF0IGNvbWUgZnJvbVxuXHRcdCAqIHRoZSBvcmlnaW4gZW1pdHRlci5cblx0XHQgKiBAdHlwZSB7RXZlbnRFbWl0dGVyfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfID0gdGFyZ2V0RW1pdHRlcjtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcCBvZiBldmVudHMgdGhhdCBzaG91bGQgYmUgcHJveGllZC4gSWYgd2hpdGVsaXN0IGlzIHNldCBibGFja2xpc3QgaXMgaWdub3JlZC5cblx0XHQgKiBAdHlwZSB7T2JqZWN0fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLndoaXRlbGlzdF8gPSB3aGl0ZWxpc3Q7XG5cblx0XHR0aGlzLnN0YXJ0UHJveHlfKCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB0aGUgZ2l2ZW4gbGlzdGVuZXIgZm9yIHRoZSBnaXZlbiBldmVudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gVGhlIGxpc3RlbmVkIGV2ZW50J3MgaGFuZGxlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRhZGRMaXN0ZW5lcl8oZXZlbnQsIGxpc3RlbmVyKSB7XG5cdFx0cmV0dXJuIHRoaXMub3JpZ2luRW1pdHRlcl8ub24oZXZlbnQsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMucmVtb3ZlTGlzdGVuZXJzXygpO1xuXHRcdHRoaXMucHJveGllZEV2ZW50c18gPSBudWxsO1xuXHRcdHRoaXMub3JpZ2luRW1pdHRlcl8gPSBudWxsO1xuXHRcdHRoaXMudGFyZ2V0RW1pdHRlcl8gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEVtaXRzIHRoZSBzcGVjaWZpZWQgZXZlbnQgdHlwZSBvbiB0aGUgdGFyZ2V0IGVtaXR0ZXIuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGVtaXRPblRhcmdldF8oLi4uYXJncykge1xuXHRcdHRoaXMudGFyZ2V0RW1pdHRlcl8uZW1pdCguLi5hcmdzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQcm94aWVzIHRoZSBnaXZlbiBldmVudCBmcm9tIHRoZSBvcmlnaW4gdG8gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICovXG5cdHByb3h5RXZlbnQoZXZlbnQpIHtcblx0XHRpZiAodGhpcy5zaG91bGRQcm94eUV2ZW50XyhldmVudCkpIHtcblx0XHRcdHRoaXMudHJ5VG9BZGRMaXN0ZW5lcl8oZXZlbnQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHRoZSBwcm94eSBsaXN0ZW5lciBmb3IgYWxsIGV2ZW50cy5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXJzXygpIHtcblx0XHRpZiAodGhpcy5wcm94aWVkRXZlbnRzXykge1xuXHRcdFx0Y29uc3QgZXZlbnRzID0gT2JqZWN0LmtleXModGhpcy5wcm94aWVkRXZlbnRzXyk7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfW2V2ZW50c1tpXV0ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHRcdH1cblx0XHRcdHRoaXMucHJveGllZEV2ZW50c18gPSBudWxsO1xuXHRcdH1cblx0XHR0aGlzLnBlbmRpbmdFdmVudHNfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGFuZ2VzIHRoZSBvcmlnaW4gZW1pdHRlci4gVGhpcyBhdXRvbWF0aWNhbGx5IGRldGFjaGVzIGFueSBldmVudHMgdGhhdFxuXHQgKiB3ZXJlIGFscmVhZHkgYmVpbmcgcHJveGllZCBmcm9tIHRoZSBwcmV2aW91cyBlbWl0dGVyLCBhbmQgc3RhcnRzIHByb3h5aW5nXG5cdCAqIHRoZW0gb24gdGhlIG5ldyBlbWl0dGVyIGluc3RlYWQuXG5cdCAqIEBwYXJhbSB7IUV2ZW50RW1pdHRlcn0gb3JpZ2luRW1pdHRlclxuXHQgKi9cblx0c2V0T3JpZ2luRW1pdHRlcihvcmlnaW5FbWl0dGVyKSB7XG5cdFx0Y29uc3QgZXZlbnRzID1cblx0XHRcdHRoaXMub3JpZ2luRW1pdHRlcl8gJiYgdGhpcy5wcm94aWVkRXZlbnRzX1xuXHRcdFx0XHQ/IE9iamVjdC5rZXlzKHRoaXMucHJveGllZEV2ZW50c18pXG5cdFx0XHRcdDogdGhpcy5wZW5kaW5nRXZlbnRzXztcblx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfID0gb3JpZ2luRW1pdHRlcjtcblx0XHRpZiAoZXZlbnRzKSB7XG5cdFx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyc18oKTtcblx0XHRcdGV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHRoaXMucHJveHlFdmVudChldmVudCkpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGV2ZW50IHNob3VsZCBiZSBwcm94aWVkLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0c2hvdWxkUHJveHlFdmVudF8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy53aGl0ZWxpc3RfICYmICF0aGlzLndoaXRlbGlzdF9bZXZlbnRdKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICh0aGlzLmJsYWNrbGlzdF8gJiYgdGhpcy5ibGFja2xpc3RfW2V2ZW50XSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gIXRoaXMucHJveGllZEV2ZW50c18gfHwgIXRoaXMucHJveGllZEV2ZW50c19bZXZlbnRdO1xuXHR9XG5cblx0LyoqXG5cdCAqIFN0YXJ0cyBwcm94eWluZyBhbGwgZXZlbnRzIGZyb20gdGhlIG9yaWdpbiB0byB0aGUgdGFyZ2V0IGVtaXR0ZXIuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHN0YXJ0UHJveHlfKCkge1xuXHRcdHRoaXMudGFyZ2V0RW1pdHRlcl8ub25MaXN0ZW5lcih0aGlzLnByb3h5RXZlbnQuYmluZCh0aGlzKSk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBvcmlnaW4gZW1pdHRlciwgaWYgaXQgZXhpc3RzLiBPdGhlcndpc2UsIHN0b3Jlc1xuXHQgKiB0aGUgcGVuZGluZyBsaXN0ZW5lciBzbyBpdCBjYW4gYmUgdXNlZCBvbiBhIGZ1dHVyZSBvcmlnaW4gZW1pdHRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHRyeVRvQWRkTGlzdGVuZXJfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMub3JpZ2luRW1pdHRlcl8pIHtcblx0XHRcdHRoaXMucHJveGllZEV2ZW50c18gPSB0aGlzLnByb3hpZWRFdmVudHNfIHx8IHt9O1xuXHRcdFx0dGhpcy5wcm94aWVkRXZlbnRzX1tldmVudF0gPSB0aGlzLmFkZExpc3RlbmVyXyhcblx0XHRcdFx0ZXZlbnQsXG5cdFx0XHRcdHRoaXMuZW1pdE9uVGFyZ2V0Xy5iaW5kKHRoaXMsIGV2ZW50KVxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5wZW5kaW5nRXZlbnRzXyA9IHRoaXMucGVuZGluZ0V2ZW50c18gfHwgW107XG5cdFx0XHR0aGlzLnBlbmRpbmdFdmVudHNfLnB1c2goZXZlbnQpO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudEVtaXR0ZXJQcm94eTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtEaXNwb3NhYmxlfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogRXZlbnRIYW5kbGVyIHV0aWxpdHkuIEl0J3MgdXNlZnVsIGZvciBlYXNpbHkgcmVtb3ZpbmcgYSBncm91cCBvZlxuICogbGlzdGVuZXJzIGZyb20gZGlmZmVyZW50IEV2ZW50RW1pdHRlciBpbnN0YW5jZXMuXG4gKiBAZXh0ZW5kcyB7RGlzcG9zYWJsZX1cbiAqL1xuY2xhc3MgRXZlbnRIYW5kbGVyIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBFdmVudEhhbmRsZXIgY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBBbiBhcnJheSB0aGF0IGhvbGRzIHRoZSBhZGRlZCBldmVudCBoYW5kbGVzLCBzbyB0aGUgbGlzdGVuZXJzIGNhbiBiZVxuXHRcdCAqIHJlbW92ZWQgbGF0ZXIuXG5cdFx0ICogQHR5cGUge0FycmF5LjxFdmVudEhhbmRsZT59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZXZlbnRIYW5kbGVzXyA9IFtdO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgZXZlbnQgaGFuZGxlcyB0byBiZSByZW1vdmVkIGxhdGVyIHRocm91Z2ggdGhlIGByZW1vdmVBbGxMaXN0ZW5lcnNgXG5cdCAqIG1ldGhvZC5cblx0ICogQHBhcmFtIHsuLi4oIUV2ZW50SGFuZGxlKX0gdmFyX2FyZ3Ncblx0ICovXG5cdGFkZCguLi5hcmdzKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRIYW5kbGVzXy5wdXNoKGFyZ3NbaV0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBvZiB0aGlzIGluc3RhbmNlJ3Mgb2JqZWN0IHJlZmVyZW5jZXMuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMuZXZlbnRIYW5kbGVzXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBhbGwgbGlzdGVuZXJzIHRoYXQgaGF2ZSBiZWVuIGFkZGVkIHRocm91Z2ggdGhlIGBhZGRgIG1ldGhvZC5cblx0ICovXG5cdHJlbW92ZUFsbExpc3RlbmVycygpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZXZlbnRIYW5kbGVzXy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5ldmVudEhhbmRsZXNfW2ldLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5ldmVudEhhbmRsZXNfID0gW107XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRIYW5kbGVyO1xuIiwiLyohXG4gKiBQcm9taXNlcyBwb2x5ZmlsbCBmcm9tIEdvb2dsZSdzIENsb3N1cmUgTGlicmFyeS5cbiAqXG4gKiAgICAgIENvcHlyaWdodCAyMDEzIFRoZSBDbG9zdXJlIExpYnJhcnkgQXV0aG9ycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBOT1RFKGVkdWFyZG8pOiBQcm9taXNlIHN1cHBvcnQgaXMgbm90IHJlYWR5IG9uIGFsbCBzdXBwb3J0ZWQgYnJvd3NlcnMsXG4gKiB0aGVyZWZvcmUgbWV0YWwtcHJvbWlzZSBpcyB0ZW1wb3JhcmlseSB1c2luZyBHb29nbGUncyBwcm9taXNlcyBhcyBwb2x5ZmlsbC5cbiAqIEl0IHN1cHBvcnRzIGNhbmNlbGxhYmxlIHByb21pc2VzIGFuZCBoYXMgY2xlYW4gYW5kIGZhc3QgaW1wbGVtZW50YXRpb24uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0RlZiwgaXNGdW5jdGlvbiwgaXNPYmplY3QgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgeyBhc3luYyB9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBQcm92aWRlcyBhIG1vcmUgc3RyaWN0IGludGVyZmFjZSBmb3IgVGhlbmFibGVzIGluIHRlcm1zIG9mXG4gKiBodHRwOi8vcHJvbWlzZXNhcGx1cy5jb20gZm9yIGludGVyb3Agd2l0aCB7QHNlZSBDYW5jZWxsYWJsZVByb21pc2V9LlxuICpcbiAqIEBpbnRlcmZhY2VcbiAqIEBleHRlbmRzIHtJVGhlbmFibGUuPFRZUEU+fVxuICogQHRlbXBsYXRlIFRZUEVcbiAqL1xudmFyIFRoZW5hYmxlID0gZnVuY3Rpb24oKSB7fTtcblxuLyoqXG4gKiBBZGRzIGNhbGxiYWNrcyB0aGF0IHdpbGwgb3BlcmF0ZSBvbiB0aGUgcmVzdWx0IG9mIHRoZSBUaGVuYWJsZSwgcmV0dXJuaW5nIGFcbiAqIG5ldyBjaGlsZCBQcm9taXNlLlxuICpcbiAqIElmIHRoZSBUaGVuYWJsZSBpcyBmdWxmaWxsZWQsIHRoZSB7QGNvZGUgb25GdWxmaWxsZWR9IGNhbGxiYWNrIHdpbGwgYmVcbiAqIGludm9rZWQgd2l0aCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgYXMgYXJndW1lbnQsIGFuZCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsXG4gKiBiZSBmdWxmaWxsZWQgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjay4gSWYgdGhlIGNhbGxiYWNrIHRocm93c1xuICogYW4gZXhjZXB0aW9uLCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHRocm93biB2YWx1ZVxuICogaW5zdGVhZC5cbiAqXG4gKiBJZiB0aGUgVGhlbmFibGUgaXMgcmVqZWN0ZWQsIHRoZSB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VkXG4gKiB3aXRoIHRoZSByZWplY3Rpb24gcmVhc29uIGFzIGFyZ3VtZW50LCBhbmQgdGhlIGNoaWxkIFByb21pc2Ugd2lsbCBiZSByZWplY3RlZFxuICogd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjayBvciB0aHJvd24gdmFsdWUuXG4gKlxuICogQHBhcmFtIHs/KGZ1bmN0aW9uKHRoaXM6VEhJUywgVFlQRSk6XG4gKiAgICAgICAgICAgICAoUkVTVUxUfElUaGVuYWJsZS48UkVTVUxUPnxUaGVuYWJsZSkpPX0gb3B0X29uRnVsZmlsbGVkIEFcbiAqICAgICBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgaW52b2tlZCB3aXRoIHRoZSBmdWxmaWxsbWVudCB2YWx1ZSBpZiB0aGUgUHJvbWlzZVxuICogICAgIGlzIGZ1bGxmaWxsZWQuXG4gKiBAcGFyYW0gez8oZnVuY3Rpb24oKik6ICopPX0gb3B0X29uUmVqZWN0ZWQgQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgaW52b2tlZFxuICogICAgIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb24gaWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQuXG4gKiBAcGFyYW0ge1RISVM9fSBvcHRfY29udGV4dCBBbiBvcHRpb25hbCBjb250ZXh0IG9iamVjdCB0aGF0IHdpbGwgYmUgdGhlXG4gKiAgICAgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRoZSBjYWxsYmFja3MuIEJ5IGRlZmF1bHQsIGZ1bmN0aW9ucyBhcmUgZXhlY3V0ZWRcbiAqICAgICB3aXRoIHRoZSBkZWZhdWx0IHRoaXMuXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlLjxSRVNVTFQ+fSBBIG5ldyBQcm9taXNlIHRoYXQgd2lsbCByZWNlaXZlIHRoZVxuICogICAgIHJlc3VsdCBvZiB0aGUgZnVsZmlsbG1lbnQgb3IgcmVqZWN0aW9uIGNhbGxiYWNrLlxuICogQHRlbXBsYXRlIFJFU1VMVCxUSElTXG4gKi9cblRoZW5hYmxlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24oKSB7fTtcblxuXG4vKipcbiAqIEFuIGV4cGFuZG8gcHJvcGVydHkgdG8gaW5kaWNhdGUgdGhhdCBhbiBvYmplY3QgaW1wbGVtZW50c1xuICoge0Bjb2RlIFRoZW5hYmxlfS5cbiAqXG4gKiB7QHNlZSBhZGRJbXBsZW1lbnRhdGlvbn0uXG4gKlxuICogQGNvbnN0XG4gKi9cblRoZW5hYmxlLklNUExFTUVOVEVEX0JZX1BST1AgPSAnJGdvb2dfVGhlbmFibGUnO1xuXG5cbi8qKlxuICogTWFya3MgYSBnaXZlbiBjbGFzcyAoY29uc3RydWN0b3IpIGFzIGFuIGltcGxlbWVudGF0aW9uIG9mIFRoZW5hYmxlLCBzb1xuICogdGhhdCB3ZSBjYW4gcXVlcnkgdGhhdCBmYWN0IGF0IHJ1bnRpbWUuIFRoZSBjbGFzcyBtdXN0IGhhdmUgYWxyZWFkeVxuICogaW1wbGVtZW50ZWQgdGhlIGludGVyZmFjZS5cbiAqIEV4cG9ydHMgYSAndGhlbicgbWV0aG9kIG9uIHRoZSBjb25zdHJ1Y3RvciBwcm90b3R5cGUsIHNvIHRoYXQgdGhlIG9iamVjdHNcbiAqIGFsc28gaW1wbGVtZW50IHRoZSBleHRlcm4ge0BzZWUgVGhlbmFibGV9IGludGVyZmFjZSBmb3IgaW50ZXJvcCB3aXRoXG4gKiBvdGhlciBQcm9taXNlIGltcGxlbWVudGF0aW9ucy5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24obmV3OlRoZW5hYmxlLC4uLls/XSl9IGN0b3IgVGhlIGNsYXNzIGNvbnN0cnVjdG9yLiBUaGVcbiAqICAgICBjb3JyZXNwb25kaW5nIGNsYXNzIG11c3QgaGF2ZSBhbHJlYWR5IGltcGxlbWVudGVkIHRoZSBpbnRlcmZhY2UuXG4gKi9cblRoZW5hYmxlLmFkZEltcGxlbWVudGF0aW9uID0gZnVuY3Rpb24oY3Rvcikge1xuICBjdG9yLnByb3RvdHlwZS50aGVuID0gY3Rvci5wcm90b3R5cGUudGhlbjtcbiAgY3Rvci5wcm90b3R5cGUuJGdvb2dfVGhlbmFibGUgPSB0cnVlO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Kn0gb2JqZWN0XG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIGEgZ2l2ZW4gaW5zdGFuY2UgaW1wbGVtZW50cyB7QGNvZGUgVGhlbmFibGV9LlxuICogICAgIFRoZSBjbGFzcy9zdXBlcmNsYXNzIG9mIHRoZSBpbnN0YW5jZSBtdXN0IGNhbGwge0Bjb2RlIGFkZEltcGxlbWVudGF0aW9ufS5cbiAqL1xuVGhlbmFibGUuaXNJbXBsZW1lbnRlZEJ5ID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gIGlmICghb2JqZWN0KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHRyeSB7XG4gICAgcmV0dXJuICEhb2JqZWN0LiRnb29nX1RoZW5hYmxlO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gUHJvcGVydHkgYWNjZXNzIHNlZW1zIHRvIGJlIGZvcmJpZGRlbi5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBMaWtlIGJpbmQoKSwgZXhjZXB0IHRoYXQgYSAndGhpcyBvYmplY3QnIGlzIG5vdCByZXF1aXJlZC4gVXNlZnVsIHdoZW4gdGhlXG4gKiB0YXJnZXQgZnVuY3Rpb24gaXMgYWxyZWFkeSBib3VuZC5cbiAqXG4gKiBVc2FnZTpcbiAqIHZhciBnID0gcGFydGlhbChmLCBhcmcxLCBhcmcyKTtcbiAqIGcoYXJnMywgYXJnNCk7XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gQSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkuXG4gKiBAcGFyYW0gey4uLip9IHZhcl9hcmdzIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRoYXQgYXJlIHBhcnRpYWxseSBhcHBsaWVkIHRvIGZuLlxuICogQHJldHVybiB7IUZ1bmN0aW9ufSBBIHBhcnRpYWxseS1hcHBsaWVkIGZvcm0gb2YgdGhlIGZ1bmN0aW9uIGJpbmQoKSB3YXNcbiAqICAgICBpbnZva2VkIGFzIGEgbWV0aG9kIG9mLlxuICovXG52YXIgcGFydGlhbCA9IGZ1bmN0aW9uKGZuKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIC8vIENsb25lIHRoZSBhcnJheSAod2l0aCBzbGljZSgpKSBhbmQgYXBwZW5kIGFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAgLy8gdG8gdGhlIGV4aXN0aW5nIGFyZ3VtZW50cy5cbiAgICB2YXIgbmV3QXJncyA9IGFyZ3Muc2xpY2UoKTtcbiAgICBuZXdBcmdzLnB1c2guYXBwbHkobmV3QXJncywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgbmV3QXJncyk7XG4gIH07XG59O1xuXG4vKipcbiAqIFByb21pc2VzIHByb3ZpZGUgYSByZXN1bHQgdGhhdCBtYXkgYmUgcmVzb2x2ZWQgYXN5bmNocm9ub3VzbHkuIEEgUHJvbWlzZSBtYXlcbiAqIGJlIHJlc29sdmVkIGJ5IGJlaW5nIGZ1bGZpbGxlZCBvciByZWplY3RlZCB3aXRoIGEgdmFsdWUsIHdoaWNoIHdpbGwgYmUga25vd25cbiAqIGFzIHRoZSBmdWxmaWxsbWVudCB2YWx1ZSBvciB0aGUgcmVqZWN0aW9uIHJlYXNvbi4gV2hldGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLCB0aGUgUHJvbWlzZSByZXN1bHQgaXMgaW1tdXRhYmxlIG9uY2UgaXQgaXMgc2V0LlxuICpcbiAqIFByb21pc2VzIG1heSByZXByZXNlbnQgcmVzdWx0cyBvZiBhbnkgdHlwZSwgaW5jbHVkaW5nIHVuZGVmaW5lZC4gUmVqZWN0aW9uXG4gKiByZWFzb25zIGFyZSB0eXBpY2FsbHkgRXJyb3JzLCBidXQgbWF5IGFsc28gYmUgb2YgYW55IHR5cGUuIENsb3N1cmUgUHJvbWlzZXNcbiAqIGFsbG93IGZvciBvcHRpb25hbCB0eXBlIGFubm90YXRpb25zIHRoYXQgZW5mb3JjZSB0aGF0IGZ1bGZpbGxtZW50IHZhbHVlcyBhcmVcbiAqIG9mIHRoZSBhcHByb3ByaWF0ZSB0eXBlcyBhdCBjb21waWxlIHRpbWUuXG4gKlxuICogVGhlIHJlc3VsdCBvZiBhIFByb21pc2UgaXMgYWNjZXNzaWJsZSBieSBjYWxsaW5nIHtAY29kZSB0aGVufSBhbmQgcmVnaXN0ZXJpbmdcbiAqIHtAY29kZSBvbkZ1bGZpbGxlZH0gYW5kIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFja3MuIE9uY2UgdGhlIFByb21pc2VcbiAqIHJlc29sdmVzLCB0aGUgcmVsZXZhbnQgY2FsbGJhY2tzIGFyZSBpbnZva2VkIHdpdGggdGhlIGZ1bGZpbGxtZW50IHZhbHVlIG9yXG4gKiByZWplY3Rpb24gcmVhc29uIGFzIGFyZ3VtZW50LiBDYWxsYmFja3MgYXJlIGFsd2F5cyBpbnZva2VkIGluIHRoZSBvcmRlciB0aGV5XG4gKiB3ZXJlIHJlZ2lzdGVyZWQsIGV2ZW4gd2hlbiBhZGRpdGlvbmFsIHtAY29kZSB0aGVufSBjYWxscyBhcmUgbWFkZSBmcm9tIGluc2lkZVxuICogYW5vdGhlciBjYWxsYmFjay4gQSBjYWxsYmFjayBpcyBhbHdheXMgcnVuIGFzeW5jaHJvbm91c2x5IHNvbWV0aW1lIGFmdGVyIHRoZVxuICogc2NvcGUgY29udGFpbmluZyB0aGUgcmVnaXN0ZXJpbmcge0Bjb2RlIHRoZW59IGludm9jYXRpb24gaGFzIHJldHVybmVkLlxuICpcbiAqIElmIGEgUHJvbWlzZSBpcyByZXNvbHZlZCB3aXRoIGFub3RoZXIgUHJvbWlzZSwgdGhlIGZpcnN0IFByb21pc2Ugd2lsbCBibG9ja1xuICogdW50aWwgdGhlIHNlY29uZCBpcyByZXNvbHZlZCwgYW5kIHRoZW4gYXNzdW1lcyB0aGUgc2FtZSByZXN1bHQgYXMgdGhlIHNlY29uZFxuICogUHJvbWlzZS4gVGhpcyBhbGxvd3MgUHJvbWlzZXMgdG8gZGVwZW5kIG9uIHRoZSByZXN1bHRzIG9mIG90aGVyIFByb21pc2VzLFxuICogbGlua2luZyB0b2dldGhlciBtdWx0aXBsZSBhc3luY2hyb25vdXMgb3BlcmF0aW9ucy5cbiAqXG4gKiBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgUHJvbWlzZXMvQSsgc3BlY2lmaWNhdGlvbiBhbmRcbiAqIHBhc3NlcyB0aGF0IHNwZWNpZmljYXRpb24ncyBjb25mb3JtYW5jZSB0ZXN0IHN1aXRlLiBBIENsb3N1cmUgUHJvbWlzZSBtYXkgYmVcbiAqIHJlc29sdmVkIHdpdGggYSBQcm9taXNlIGluc3RhbmNlIChvciBzdWZmaWNpZW50bHkgY29tcGF0aWJsZSBQcm9taXNlLWxpa2VcbiAqIG9iamVjdCkgY3JlYXRlZCBieSBvdGhlciBQcm9taXNlIGltcGxlbWVudGF0aW9ucy4gRnJvbSB0aGUgc3BlY2lmaWNhdGlvbixcbiAqIFByb21pc2UtbGlrZSBvYmplY3RzIGFyZSBrbm93biBhcyBcIlRoZW5hYmxlc1wiLlxuICpcbiAqIEBzZWUgaHR0cDovL3Byb21pc2VzYXBsdXMuY29tL1xuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oXG4gKiAgICAgICAgICAgICB0aGlzOlJFU09MVkVSX0NPTlRFWFQsXG4gKiAgICAgICAgICAgICBmdW5jdGlvbigoVFlQRXxJVGhlbmFibGUuPFRZUEU+fFRoZW5hYmxlKSksXG4gKiAgICAgICAgICAgICBmdW5jdGlvbigqKSk6IHZvaWR9IHJlc29sdmVyXG4gKiAgICAgSW5pdGlhbGl6YXRpb24gZnVuY3Rpb24gdGhhdCBpcyBpbnZva2VkIGltbWVkaWF0ZWx5IHdpdGgge0Bjb2RlIHJlc29sdmV9XG4gKiAgICAgYW5kIHtAY29kZSByZWplY3R9IGZ1bmN0aW9ucyBhcyBhcmd1bWVudHMuIFRoZSBQcm9taXNlIGlzIHJlc29sdmVkIG9yXG4gKiAgICAgcmVqZWN0ZWQgd2l0aCB0aGUgZmlyc3QgYXJndW1lbnQgcGFzc2VkIHRvIGVpdGhlciBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7UkVTT0xWRVJfQ09OVEVYVD19IG9wdF9jb250ZXh0IEFuIG9wdGlvbmFsIGNvbnRleHQgZm9yIGV4ZWN1dGluZyB0aGVcbiAqICAgICByZXNvbHZlciBmdW5jdGlvbi4gSWYgdW5zcGVjaWZpZWQsIHRoZSByZXNvbHZlciBmdW5jdGlvbiB3aWxsIGJlIGV4ZWN1dGVkXG4gKiAgICAgaW4gdGhlIGRlZmF1bHQgc2NvcGUuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBzdHJ1Y3RcbiAqIEBmaW5hbFxuICogQGltcGxlbWVudHMge1RoZW5hYmxlLjxUWVBFPn1cbiAqIEB0ZW1wbGF0ZSBUWVBFLFJFU09MVkVSX0NPTlRFWFRcbiAqL1xudmFyIENhbmNlbGxhYmxlUHJvbWlzZSA9IGZ1bmN0aW9uKHJlc29sdmVyLCBvcHRfY29udGV4dCkge1xuICAvKipcbiAgICogVGhlIGludGVybmFsIHN0YXRlIG9mIHRoaXMgUHJvbWlzZS4gRWl0aGVyIFBFTkRJTkcsIEZVTEZJTExFRCwgUkVKRUNURUQsIG9yXG4gICAqIEJMT0NLRUQuXG4gICAqIEBwcml2YXRlIHtDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVffVxuICAgKi9cbiAgdGhpcy5zdGF0ZV8gPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkc7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNvbHZlZCByZXN1bHQgb2YgdGhlIFByb21pc2UuIEltbXV0YWJsZSBvbmNlIHNldCB3aXRoIGVpdGhlciBhXG4gICAqIGZ1bGZpbGxtZW50IHZhbHVlIG9yIHJlamVjdGlvbiByZWFzb24uXG4gICAqIEBwcml2YXRlIHsqfVxuICAgKi9cbiAgdGhpcy5yZXN1bHRfID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBGb3IgUHJvbWlzZXMgY3JlYXRlZCBieSBjYWxsaW5nIHtAY29kZSB0aGVuKCl9LCB0aGUgb3JpZ2luYXRpbmcgcGFyZW50LlxuICAgKiBAcHJpdmF0ZSB7Q2FuY2VsbGFibGVQcm9taXNlfVxuICAgKi9cbiAgdGhpcy5wYXJlbnRfID0gbnVsbDtcblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2Yge0Bjb2RlIG9uRnVsZmlsbGVkfSBhbmQge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrcyBhZGRlZCB0b1xuICAgKiB0aGlzIFByb21pc2UgYnkgY2FsbHMgdG8ge0Bjb2RlIHRoZW4oKX0uXG4gICAqIEBwcml2YXRlIHtBcnJheS48Q2FuY2VsbGFibGVQcm9taXNlLkNhbGxiYWNrRW50cnlfPn1cbiAgICovXG4gIHRoaXMuY2FsbGJhY2tFbnRyaWVzXyA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIFByb21pc2UgaXMgaW4gdGhlIHF1ZXVlIG9mIFByb21pc2VzIHRvIGV4ZWN1dGUuXG4gICAqIEBwcml2YXRlIHtib29sZWFufVxuICAgKi9cbiAgdGhpcy5leGVjdXRpbmdfID0gZmFsc2U7XG5cbiAgaWYgKENhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID4gMCkge1xuICAgIC8qKlxuICAgICAqIEEgdGltZW91dCBJRCB1c2VkIHdoZW4gdGhlIHtAY29kZSBVTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZfSBpcyBncmVhdGVyXG4gICAgICogdGhhbiAwIG1pbGxpc2Vjb25kcy4gVGhlIElEIGlzIHNldCB3aGVuIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBhbmRcbiAgICAgKiBjbGVhcmVkIG9ubHkgaWYgYW4ge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrIGlzIGludm9rZWQgZm9yIHRoZVxuICAgICAqIFByb21pc2UgKG9yIG9uZSBvZiBpdHMgZGVzY2VuZGFudHMpIGJlZm9yZSB0aGUgZGVsYXkgaXMgZXhjZWVkZWQuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgcmVqZWN0aW9uIGlzIG5vdCBoYW5kbGVkIGJlZm9yZSB0aGUgdGltZW91dCBjb21wbGV0ZXMsIHRoZVxuICAgICAqIHJlamVjdGlvbiByZWFzb24gaXMgcGFzc2VkIHRvIHRoZSB1bmhhbmRsZWQgcmVqZWN0aW9uIGhhbmRsZXIuXG4gICAgICogQHByaXZhdGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLnVuaGFuZGxlZFJlamVjdGlvbklkXyA9IDA7XG4gIH0gZWxzZSBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPT09IDApIHtcbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSB7QGNvZGUgVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWX0gaXMgc2V0IHRvIDAgbWlsbGlzZWNvbmRzLCBhXG4gICAgICogYm9vbGVhbiB0aGF0IGlzIHNldCBpZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCwgYW5kIHJlc2V0IHRvIGZhbHNlIGlmIGFuXG4gICAgICoge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrIGlzIGludm9rZWQgZm9yIHRoZSBQcm9taXNlIChvciBvbmUgb2YgaXRzXG4gICAgICogZGVzY2VuZGFudHMpLiBJZiB0aGUgcmVqZWN0aW9uIGlzIG5vdCBoYW5kbGVkIGJlZm9yZSB0aGUgbmV4dCB0aW1lc3RlcCxcbiAgICAgKiB0aGUgcmVqZWN0aW9uIHJlYXNvbiBpcyBwYXNzZWQgdG8gdGhlIHVuaGFuZGxlZCByZWplY3Rpb24gaGFuZGxlci5cbiAgICAgKiBAcHJpdmF0ZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLmhhZFVuaGFuZGxlZFJlamVjdGlvbl8gPSBmYWxzZTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJlc29sdmVyLmNhbGwoXG4gICAgICBvcHRfY29udGV4dCwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgc2VsZi5yZXNvbHZlXyhDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkZVTEZJTExFRCwgdmFsdWUpO1xuICAgICAgfSwgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICAgIHNlbGYucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCwgcmVhc29uKTtcbiAgICAgIH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhpcy5yZXNvbHZlXyhDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVELCBlKTtcbiAgfVxufTtcblxuLyoqXG4gKiBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSBhIHJlamVjdGVkIFByb21pc2UncyByZWFzb24gaXMgcGFzc2VkIHRvXG4gKiB0aGUgcmVqZWN0aW9uIGhhbmRsZXIuIEJ5IGRlZmF1bHQsIHRoZSByZWplY3Rpb24gaGFuZGxlciByZXRocm93cyB0aGVcbiAqIHJlamVjdGlvbiByZWFzb24gc28gdGhhdCBpdCBhcHBlYXJzIGluIHRoZSBkZXZlbG9wZXIgY29uc29sZSBvclxuICoge0Bjb2RlIHdpbmRvdy5vbmVycm9yfSBoYW5kbGVyLlxuICogUmVqZWN0aW9ucyBhcmUgcmV0aHJvd24gYXMgcXVpY2tseSBhcyBwb3NzaWJsZSBieSBkZWZhdWx0LiBBIG5lZ2F0aXZlIHZhbHVlXG4gKiBkaXNhYmxlcyByZWplY3Rpb24gaGFuZGxpbmcgZW50aXJlbHkuXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA9IDA7XG5cblxuLyoqXG4gKiBUaGUgcG9zc2libGUgaW50ZXJuYWwgc3RhdGVzIGZvciBhIFByb21pc2UuIFRoZXNlIHN0YXRlcyBhcmUgbm90IGRpcmVjdGx5XG4gKiBvYnNlcnZhYmxlIHRvIGV4dGVybmFsIGNhbGxlcnMuXG4gKiBAZW51bSB7bnVtYmVyfVxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXyA9IHtcbiAgLyoqIFRoZSBQcm9taXNlIGlzIHdhaXRpbmcgZm9yIHJlc29sdXRpb24uICovXG4gIFBFTkRJTkc6IDAsXG5cbiAgLyoqIFRoZSBQcm9taXNlIGlzIGJsb2NrZWQgd2FpdGluZyBmb3IgdGhlIHJlc3VsdCBvZiBhbm90aGVyIFRoZW5hYmxlLiAqL1xuICBCTE9DS0VEOiAxLFxuXG4gIC8qKiBUaGUgUHJvbWlzZSBoYXMgYmVlbiByZXNvbHZlZCB3aXRoIGEgZnVsZmlsbG1lbnQgdmFsdWUuICovXG4gIEZVTEZJTExFRDogMixcblxuICAvKiogVGhlIFByb21pc2UgaGFzIGJlZW4gcmVzb2x2ZWQgd2l0aCBhIHJlamVjdGlvbiByZWFzb24uICovXG4gIFJFSkVDVEVEOiAzXG59O1xuXG5cbi8qKlxuICogVHlwZWRlZiBmb3IgZW50cmllcyBpbiB0aGUgY2FsbGJhY2sgY2hhaW4uIEVhY2ggY2FsbCB0byB7QGNvZGUgdGhlbn0sXG4gKiB7QGNvZGUgdGhlbkNhdGNofSwgb3Ige0Bjb2RlIHRoZW5BbHdheXN9IGNyZWF0ZXMgYW4gZW50cnkgY29udGFpbmluZyB0aGVcbiAqIGZ1bmN0aW9ucyB0aGF0IG1heSBiZSBpbnZva2VkIG9uY2UgdGhlIFByb21pc2UgaXMgcmVzb2x2ZWQuXG4gKlxuICogQHR5cGVkZWYge3tcbiAqICAgY2hpbGQ6IENhbmNlbGxhYmxlUHJvbWlzZSxcbiAqICAgb25GdWxmaWxsZWQ6IGZ1bmN0aW9uKCopLFxuICogICBvblJlamVjdGVkOiBmdW5jdGlvbigqKVxuICogfX1cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5DYWxsYmFja0VudHJ5XyA9IG51bGw7XG5cblxuLyoqXG4gKiBAcGFyYW0geyhUWVBFfFRoZW5hYmxlLjxUWVBFPnxUaGVuYWJsZSk9fSBvcHRfdmFsdWVcbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPFRZUEU+fSBBIG5ldyBQcm9taXNlIHRoYXQgaXMgaW1tZWRpYXRlbHkgcmVzb2x2ZWRcbiAqICAgICB3aXRoIHRoZSBnaXZlbiB2YWx1ZS5cbiAqIEB0ZW1wbGF0ZSBUWVBFXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlID0gZnVuY3Rpb24ob3B0X3ZhbHVlKSB7XG4gIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcbiAgICAgIHJlc29sdmUob3B0X3ZhbHVlKTtcbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0geyo9fSBvcHRfcmVhc29uXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlfSBBIG5ldyBQcm9taXNlIHRoYXQgaXMgaW1tZWRpYXRlbHkgcmVqZWN0ZWQgd2l0aCB0aGVcbiAqICAgICBnaXZlbiByZWFzb24uXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5yZWplY3QgPSBmdW5jdGlvbihvcHRfcmVhc29uKSB7XG4gIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgcmVqZWN0KG9wdF9yZWFzb24pO1xuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7IUFycmF5LjwhKFRoZW5hYmxlLjxUWVBFPnxUaGVuYWJsZSk+fSBwcm9taXNlc1xuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48VFlQRT59IEEgUHJvbWlzZSB0aGF0IHJlY2VpdmVzIHRoZSByZXN1bHQgb2YgdGhlXG4gKiAgICAgZmlyc3QgUHJvbWlzZSAob3IgUHJvbWlzZS1saWtlKSBpbnB1dCB0byBjb21wbGV0ZS5cbiAqIEB0ZW1wbGF0ZSBUWVBFXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5yYWNlID0gZnVuY3Rpb24ocHJvbWlzZXMpIHtcbiAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBpZiAoIXByb21pc2VzLmxlbmd0aCkge1xuICAgICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgICBmb3IgKHZhciBpID0gMCwgcHJvbWlzZTsgKHByb21pc2UgPSBwcm9taXNlc1tpXSk7IGkrKykge1xuICAgICAgICBwcm9taXNlLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0geyFBcnJheS48IShUaGVuYWJsZS48VFlQRT58VGhlbmFibGUpPn0gcHJvbWlzZXNcbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPCFBcnJheS48VFlQRT4+fSBBIFByb21pc2UgdGhhdCByZWNlaXZlcyBhIGxpc3Qgb2ZcbiAqICAgICBldmVyeSBmdWxmaWxsZWQgdmFsdWUgb25jZSBldmVyeSBpbnB1dCBQcm9taXNlIChvciBQcm9taXNlLWxpa2UpIGlzXG4gKiAgICAgc3VjY2Vzc2Z1bGx5IGZ1bGZpbGxlZCwgb3IgaXMgcmVqZWN0ZWQgYnkgdGhlIGZpcnN0IHJlamVjdGlvbiByZXN1bHQuXG4gKiBAdGVtcGxhdGUgVFlQRVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuYWxsID0gZnVuY3Rpb24ocHJvbWlzZXMpIHtcbiAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgdG9GdWxmaWxsID0gcHJvbWlzZXMubGVuZ3RoO1xuICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuXG4gICAgICBpZiAoIXRvRnVsZmlsbCkge1xuICAgICAgICByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIG9uRnVsZmlsbCA9IGZ1bmN0aW9uKGluZGV4LCB2YWx1ZSkge1xuICAgICAgICB0b0Z1bGZpbGwtLTtcbiAgICAgICAgdmFsdWVzW2luZGV4XSA9IHZhbHVlO1xuICAgICAgICBpZiAodG9GdWxmaWxsID09PSAwKSB7XG4gICAgICAgICAgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICB2YXIgb25SZWplY3QgPSBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgICB9O1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgcHJvbWlzZTsgKHByb21pc2UgPSBwcm9taXNlc1tpXSk7IGkrKykge1xuICAgICAgICBwcm9taXNlLnRoZW4ocGFydGlhbChvbkZ1bGZpbGwsIGkpLCBvblJlamVjdCk7XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHshQXJyYXkuPCEoVGhlbmFibGUuPFRZUEU+fFRoZW5hYmxlKT59IHByb21pc2VzXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlLjxUWVBFPn0gQSBQcm9taXNlIHRoYXQgcmVjZWl2ZXMgdGhlIHZhbHVlIG9mXG4gKiAgICAgdGhlIGZpcnN0IGlucHV0IHRvIGJlIGZ1bGZpbGxlZCwgb3IgaXMgcmVqZWN0ZWQgd2l0aCBhIGxpc3Qgb2YgZXZlcnlcbiAqICAgICByZWplY3Rpb24gcmVhc29uIGlmIGFsbCBpbnB1dHMgYXJlIHJlamVjdGVkLlxuICogQHRlbXBsYXRlIFRZUEVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLmZpcnN0RnVsZmlsbGVkID0gZnVuY3Rpb24ocHJvbWlzZXMpIHtcbiAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgdG9SZWplY3QgPSBwcm9taXNlcy5sZW5ndGg7XG4gICAgICB2YXIgcmVhc29ucyA9IFtdO1xuXG4gICAgICBpZiAoIXRvUmVqZWN0KSB7XG4gICAgICAgIHJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgb25GdWxmaWxsID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgb25SZWplY3QgPSBmdW5jdGlvbihpbmRleCwgcmVhc29uKSB7XG4gICAgICAgIHRvUmVqZWN0LS07XG4gICAgICAgIHJlYXNvbnNbaW5kZXhdID0gcmVhc29uO1xuICAgICAgICBpZiAodG9SZWplY3QgPT09IDApIHtcbiAgICAgICAgICByZWplY3QocmVhc29ucyk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBwcm9taXNlOyAocHJvbWlzZSA9IHByb21pc2VzW2ldKTsgaSsrKSB7XG4gICAgICAgIHByb21pc2UudGhlbihvbkZ1bGZpbGwsIHBhcnRpYWwob25SZWplY3QsIGkpKTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBBZGRzIGNhbGxiYWNrcyB0aGF0IHdpbGwgb3BlcmF0ZSBvbiB0aGUgcmVzdWx0IG9mIHRoZSBQcm9taXNlLCByZXR1cm5pbmcgYVxuICogbmV3IGNoaWxkIFByb21pc2UuXG4gKlxuICogSWYgdGhlIFByb21pc2UgaXMgZnVsZmlsbGVkLCB0aGUge0Bjb2RlIG9uRnVsZmlsbGVkfSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWRcbiAqIHdpdGggdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGFzIGFyZ3VtZW50LCBhbmQgdGhlIGNoaWxkIFByb21pc2Ugd2lsbCBiZVxuICogZnVsZmlsbGVkIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgY2FsbGJhY2suIElmIHRoZSBjYWxsYmFjayB0aHJvd3MgYW5cbiAqIGV4Y2VwdGlvbiwgdGhlIGNoaWxkIFByb21pc2Ugd2lsbCBiZSByZWplY3RlZCB3aXRoIHRoZSB0aHJvd24gdmFsdWUgaW5zdGVhZC5cbiAqXG4gKiBJZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCwgdGhlIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWRcbiAqIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb24gYXMgYXJndW1lbnQsIGFuZCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkXG4gKiB3aXRoIHRoZSByZXR1cm4gdmFsdWUgKG9yIHRocm93biB2YWx1ZSkgb2YgdGhlIGNhbGxiYWNrLlxuICpcbiAqIEBvdmVycmlkZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbihvcHRfb25GdWxmaWxsZWQsIG9wdF9vblJlamVjdGVkLCBvcHRfY29udGV4dCkge1xuICByZXR1cm4gdGhpcy5hZGRDaGlsZFByb21pc2VfKFxuICAgIGlzRnVuY3Rpb24ob3B0X29uRnVsZmlsbGVkKSA/IG9wdF9vbkZ1bGZpbGxlZCA6IG51bGwsXG4gICAgaXNGdW5jdGlvbihvcHRfb25SZWplY3RlZCkgPyBvcHRfb25SZWplY3RlZCA6IG51bGwsXG4gICAgb3B0X2NvbnRleHQpO1xufTtcblRoZW5hYmxlLmFkZEltcGxlbWVudGF0aW9uKENhbmNlbGxhYmxlUHJvbWlzZSk7XG5cblxuLyoqXG4gKiBBZGRzIGEgY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGludm9rZWQgd2hldGhlciB0aGUgUHJvbWlzZSBpcyBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiBUaGUgY2FsbGJhY2sgcmVjZWl2ZXMgbm8gYXJndW1lbnQsIGFuZCBubyBuZXcgY2hpbGQgUHJvbWlzZSBpc1xuICogY3JlYXRlZC4gVGhpcyBpcyB1c2VmdWwgZm9yIGVuc3VyaW5nIHRoYXQgY2xlYW51cCB0YWtlcyBwbGFjZSBhZnRlciBjZXJ0YWluXG4gKiBhc3luY2hyb25vdXMgb3BlcmF0aW9ucy4gQ2FsbGJhY2tzIGFkZGVkIHdpdGgge0Bjb2RlIHRoZW5BbHdheXN9IHdpbGwgYmVcbiAqIGV4ZWN1dGVkIGluIHRoZSBzYW1lIG9yZGVyIHdpdGggb3RoZXIgY2FsbHMgdG8ge0Bjb2RlIHRoZW59LFxuICoge0Bjb2RlIHRoZW5BbHdheXN9LCBvciB7QGNvZGUgdGhlbkNhdGNofS5cbiAqXG4gKiBTaW5jZSBpdCBkb2VzIG5vdCBwcm9kdWNlIGEgbmV3IGNoaWxkIFByb21pc2UsIGNhbmNlbGxhdGlvbiBwcm9wYWdhdGlvbiBpc1xuICogbm90IHByZXZlbnRlZCBieSBhZGRpbmcgY2FsbGJhY2tzIHdpdGgge0Bjb2RlIHRoZW5BbHdheXN9LiBBIFByb21pc2UgdGhhdCBoYXNcbiAqIGEgY2xlYW51cCBoYW5kbGVyIGFkZGVkIHdpdGgge0Bjb2RlIHRoZW5BbHdheXN9IHdpbGwgYmUgY2FuY2VsZWQgaWYgYWxsIG9mXG4gKiBpdHMgY2hpbGRyZW4gY3JlYXRlZCBieSB7QGNvZGUgdGhlbn0gKG9yIHtAY29kZSB0aGVuQ2F0Y2h9KSBhcmUgY2FuY2VsZWQuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbih0aGlzOlRISVMpOiB2b2lkfSBvblJlc29sdmVkIEEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGludm9rZWRcbiAqICAgICB3aGVuIHRoZSBQcm9taXNlIGlzIHJlc29sdmVkLlxuICogQHBhcmFtIHtUSElTPX0gb3B0X2NvbnRleHQgQW4gb3B0aW9uYWwgY29udGV4dCBvYmplY3QgdGhhdCB3aWxsIGJlIHRoZVxuICogICAgIGV4ZWN1dGlvbiBjb250ZXh0IGZvciB0aGUgY2FsbGJhY2tzLiBCeSBkZWZhdWx0LCBmdW5jdGlvbnMgYXJlIGV4ZWN1dGVkXG4gKiAgICAgaW4gdGhlIGdsb2JhbCBzY29wZS5cbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPFRZUEU+fSBUaGlzIFByb21pc2UsIGZvciBjaGFpbmluZyBhZGRpdGlvbmFsIGNhbGxzLlxuICogQHRlbXBsYXRlIFRISVNcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50aGVuQWx3YXlzID0gZnVuY3Rpb24ob25SZXNvbHZlZCwgb3B0X2NvbnRleHQpIHtcbiAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEVuc3VyZSB0aGF0IG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkIHRvIG9uUmVzb2x2ZWQuXG4gICAgICBvblJlc29sdmVkLmNhbGwob3B0X2NvbnRleHQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgQ2FuY2VsbGFibGVQcm9taXNlLmhhbmRsZVJlamVjdGlvbl8uY2FsbChudWxsLCBlcnIpO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmFkZENhbGxiYWNrRW50cnlfKHtcbiAgICBjaGlsZDogbnVsbCxcbiAgICBvblJlamVjdGVkOiBjYWxsYmFjayxcbiAgICBvbkZ1bGZpbGxlZDogY2FsbGJhY2tcbiAgfSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIEFkZHMgYSBjYWxsYmFjayB0aGF0IHdpbGwgYmUgaW52b2tlZCBvbmx5IGlmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLiBUaGlzXG4gKiBpcyBlcXVpdmFsZW50IHRvIHtAY29kZSB0aGVuKG51bGwsIG9uUmVqZWN0ZWQpfS5cbiAqXG4gKiBAcGFyYW0geyFmdW5jdGlvbih0aGlzOlRISVMsICopOiAqfSBvblJlamVjdGVkIEEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlXG4gKiAgICAgaW52b2tlZCB3aXRoIHRoZSByZWplY3Rpb24gcmVhc29uIGlmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLlxuICogQHBhcmFtIHtUSElTPX0gb3B0X2NvbnRleHQgQW4gb3B0aW9uYWwgY29udGV4dCBvYmplY3QgdGhhdCB3aWxsIGJlIHRoZVxuICogICAgIGV4ZWN1dGlvbiBjb250ZXh0IGZvciB0aGUgY2FsbGJhY2tzLiBCeSBkZWZhdWx0LCBmdW5jdGlvbnMgYXJlIGV4ZWN1dGVkXG4gKiAgICAgaW4gdGhlIGdsb2JhbCBzY29wZS5cbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9IEEgbmV3IFByb21pc2UgdGhhdCB3aWxsIHJlY2VpdmUgdGhlIHJlc3VsdCBvZiB0aGVcbiAqICAgICBjYWxsYmFjay5cbiAqIEB0ZW1wbGF0ZSBUSElTXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbkNhdGNoID0gZnVuY3Rpb24ob25SZWplY3RlZCwgb3B0X2NvbnRleHQpIHtcbiAgcmV0dXJuIHRoaXMuYWRkQ2hpbGRQcm9taXNlXyhudWxsLCBvblJlamVjdGVkLCBvcHRfY29udGV4dCk7XG59O1xuXG4vKipcbiAqIEFsaWFzIG9mIHtAbGluayBDYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRoZW5DYXRjaH1cbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5jYXRjaCA9IENhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbkNhdGNoO1xuXG5cbi8qKlxuICogQ2FuY2VscyB0aGUgUHJvbWlzZSBpZiBpdCBpcyBzdGlsbCBwZW5kaW5nIGJ5IHJlamVjdGluZyBpdCB3aXRoIGEgY2FuY2VsXG4gKiBFcnJvci4gTm8gYWN0aW9uIGlzIHBlcmZvcm1lZCBpZiB0aGUgUHJvbWlzZSBpcyBhbHJlYWR5IHJlc29sdmVkLlxuICpcbiAqIEFsbCBjaGlsZCBQcm9taXNlcyBvZiB0aGUgY2FuY2VsZWQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHNhbWVcbiAqIGNhbmNlbCBlcnJvciwgYXMgd2l0aCBub3JtYWwgUHJvbWlzZSByZWplY3Rpb24uIElmIHRoZSBQcm9taXNlIHRvIGJlIGNhbmNlbGVkXG4gKiBpcyB0aGUgb25seSBjaGlsZCBvZiBhIHBlbmRpbmcgUHJvbWlzZSwgdGhlIHBhcmVudCBQcm9taXNlIHdpbGwgYWxzbyBiZVxuICogY2FuY2VsZWQuIENhbmNlbGxhdGlvbiBtYXkgcHJvcGFnYXRlIHVwd2FyZCB0aHJvdWdoIG11bHRpcGxlIGdlbmVyYXRpb25zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X21lc3NhZ2UgQW4gb3B0aW9uYWwgZGVidWdnaW5nIG1lc3NhZ2UgZm9yIGRlc2NyaWJpbmcgdGhlXG4gKiAgICAgY2FuY2VsbGF0aW9uIHJlYXNvbi5cbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5jYW5jZWwgPSBmdW5jdGlvbihvcHRfbWVzc2FnZSkge1xuICBpZiAodGhpcy5zdGF0ZV8gPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORykge1xuICAgIGFzeW5jLnJ1bihmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yKG9wdF9tZXNzYWdlKTtcbiAgICAgIGVyci5JU19DQU5DRUxMQVRJT05fRVJST1IgPSB0cnVlO1xuICAgICAgdGhpcy5jYW5jZWxJbnRlcm5hbF8oZXJyKTtcbiAgICB9LCB0aGlzKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIENhbmNlbHMgdGhpcyBQcm9taXNlIHdpdGggdGhlIGdpdmVuIGVycm9yLlxuICpcbiAqIEBwYXJhbSB7IUVycm9yfSBlcnIgVGhlIGNhbmNlbGxhdGlvbiBlcnJvci5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuY2FuY2VsSW50ZXJuYWxfID0gZnVuY3Rpb24oZXJyKSB7XG4gIGlmICh0aGlzLnN0YXRlXyA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HKSB7XG4gICAgaWYgKHRoaXMucGFyZW50Xykge1xuICAgICAgLy8gQ2FuY2VsIHRoZSBQcm9taXNlIGFuZCByZW1vdmUgaXQgZnJvbSB0aGUgcGFyZW50J3MgY2hpbGQgbGlzdC5cbiAgICAgIHRoaXMucGFyZW50Xy5jYW5jZWxDaGlsZF8odGhpcywgZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZXNvbHZlXyhDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVELCBlcnIpO1xuICAgIH1cbiAgfVxufTtcblxuXG4vKipcbiAqIENhbmNlbHMgYSBjaGlsZCBQcm9taXNlIGZyb20gdGhlIGxpc3Qgb2YgY2FsbGJhY2sgZW50cmllcy4gSWYgdGhlIFByb21pc2UgaGFzXG4gKiBub3QgYWxyZWFkeSBiZWVuIHJlc29sdmVkLCByZWplY3QgaXQgd2l0aCBhIGNhbmNlbCBlcnJvci4gSWYgdGhlcmUgYXJlIG5vXG4gKiBvdGhlciBjaGlsZHJlbiBpbiB0aGUgbGlzdCBvZiBjYWxsYmFjayBlbnRyaWVzLCBwcm9wYWdhdGUgdGhlIGNhbmNlbGxhdGlvblxuICogYnkgY2FuY2VsaW5nIHRoaXMgUHJvbWlzZSBhcyB3ZWxsLlxuICpcbiAqIEBwYXJhbSB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gY2hpbGRQcm9taXNlIFRoZSBQcm9taXNlIHRvIGNhbmNlbC5cbiAqIEBwYXJhbSB7IUVycm9yfSBlcnIgVGhlIGNhbmNlbCBlcnJvciB0byB1c2UgZm9yIHJlamVjdGluZyB0aGUgUHJvbWlzZS5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuY2FuY2VsQ2hpbGRfID0gZnVuY3Rpb24oY2hpbGRQcm9taXNlLCBlcnIpIHtcbiAgaWYgKCF0aGlzLmNhbGxiYWNrRW50cmllc18pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGNoaWxkQ291bnQgPSAwO1xuICB2YXIgY2hpbGRJbmRleCA9IC0xO1xuXG4gIC8vIEZpbmQgdGhlIGNhbGxiYWNrIGVudHJ5IGZvciB0aGUgY2hpbGRQcm9taXNlLCBhbmQgY291bnQgd2hldGhlciB0aGVyZSBhcmVcbiAgLy8gYWRkaXRpb25hbCBjaGlsZCBQcm9taXNlcy5cbiAgZm9yICh2YXIgaSA9IDAsIGVudHJ5OyAoZW50cnkgPSB0aGlzLmNhbGxiYWNrRW50cmllc19baV0pOyBpKyspIHtcbiAgICB2YXIgY2hpbGQgPSBlbnRyeS5jaGlsZDtcbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGNoaWxkQ291bnQrKztcbiAgICAgIGlmIChjaGlsZCA9PT0gY2hpbGRQcm9taXNlKSB7XG4gICAgICAgIGNoaWxkSW5kZXggPSBpO1xuICAgICAgfVxuICAgICAgaWYgKGNoaWxkSW5kZXggPj0gMCAmJiBjaGlsZENvdW50ID4gMSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBJZiB0aGUgY2hpbGQgUHJvbWlzZSB3YXMgdGhlIG9ubHkgY2hpbGQsIGNhbmNlbCB0aGlzIFByb21pc2UgYXMgd2VsbC5cbiAgLy8gT3RoZXJ3aXNlLCByZWplY3Qgb25seSB0aGUgY2hpbGQgUHJvbWlzZSB3aXRoIHRoZSBjYW5jZWwgZXJyb3IuXG4gIGlmIChjaGlsZEluZGV4ID49IDApIHtcbiAgICBpZiAodGhpcy5zdGF0ZV8gPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORyAmJiBjaGlsZENvdW50ID09PSAxKSB7XG4gICAgICB0aGlzLmNhbmNlbEludGVybmFsXyhlcnIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY2FsbGJhY2tFbnRyeSA9IHRoaXMuY2FsbGJhY2tFbnRyaWVzXy5zcGxpY2UoY2hpbGRJbmRleCwgMSlbMF07XG4gICAgICB0aGlzLmV4ZWN1dGVDYWxsYmFja18oXG4gICAgICAgIGNhbGxiYWNrRW50cnksIENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQsIGVycik7XG4gICAgfVxuICB9XG59O1xuXG5cbi8qKlxuICogQWRkcyBhIGNhbGxiYWNrIGVudHJ5IHRvIHRoZSBjdXJyZW50IFByb21pc2UsIGFuZCBzY2hlZHVsZXMgY2FsbGJhY2tcbiAqIGV4ZWN1dGlvbiBpZiB0aGUgUHJvbWlzZSBoYXMgYWxyZWFkeSBiZWVuIHJlc29sdmVkLlxuICpcbiAqIEBwYXJhbSB7Q2FuY2VsbGFibGVQcm9taXNlLkNhbGxiYWNrRW50cnlffSBjYWxsYmFja0VudHJ5IFJlY29yZCBjb250YWluaW5nXG4gKiAgICAge0Bjb2RlIG9uRnVsZmlsbGVkfSBhbmQge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrcyB0byBleGVjdXRlIGFmdGVyXG4gKiAgICAgdGhlIFByb21pc2UgaXMgcmVzb2x2ZWQuXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmFkZENhbGxiYWNrRW50cnlfID0gZnVuY3Rpb24oY2FsbGJhY2tFbnRyeSkge1xuICBpZiAoKCF0aGlzLmNhbGxiYWNrRW50cmllc18gfHwgIXRoaXMuY2FsbGJhY2tFbnRyaWVzXy5sZW5ndGgpICYmXG4gICAgKHRoaXMuc3RhdGVfID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkZVTEZJTExFRCB8fFxuICAgIHRoaXMuc3RhdGVfID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVEKSkge1xuICAgIHRoaXMuc2NoZWR1bGVDYWxsYmFja3NfKCk7XG4gIH1cbiAgaWYgKCF0aGlzLmNhbGxiYWNrRW50cmllc18pIHtcbiAgICB0aGlzLmNhbGxiYWNrRW50cmllc18gPSBbXTtcbiAgfVxuICB0aGlzLmNhbGxiYWNrRW50cmllc18ucHVzaChjYWxsYmFja0VudHJ5KTtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGVzIGEgY2hpbGQgUHJvbWlzZSBhbmQgYWRkcyBpdCB0byB0aGUgY2FsbGJhY2sgZW50cnkgbGlzdC4gVGhlIHJlc3VsdCBvZlxuICogdGhlIGNoaWxkIFByb21pc2UgaXMgZGV0ZXJtaW5lZCBieSB0aGUgc3RhdGUgb2YgdGhlIHBhcmVudCBQcm9taXNlIGFuZCB0aGVcbiAqIHJlc3VsdCBvZiB0aGUge0Bjb2RlIG9uRnVsZmlsbGVkfSBvciB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tzIGFzXG4gKiBzcGVjaWZpZWQgaW4gdGhlIFByb21pc2UgcmVzb2x1dGlvbiBwcm9jZWR1cmUuXG4gKlxuICogQHNlZSBodHRwOi8vcHJvbWlzZXNhcGx1cy5jb20vI3RoZV9fbWV0aG9kXG4gKlxuICogQHBhcmFtIHs/ZnVuY3Rpb24odGhpczpUSElTLCBUWVBFKTpcbiAqICAgICAgICAgIChSRVNVTFR8Q2FuY2VsbGFibGVQcm9taXNlLjxSRVNVTFQ+fFRoZW5hYmxlKX0gb25GdWxmaWxsZWQgQSBjYWxsYmFjayB0aGF0XG4gKiAgICAgd2lsbCBiZSBpbnZva2VkIGlmIHRoZSBQcm9taXNlIGlzIGZ1bGxmaWxsZWQsIG9yIG51bGwuXG4gKiBAcGFyYW0gez9mdW5jdGlvbih0aGlzOlRISVMsICopOiAqfSBvblJlamVjdGVkIEEgY2FsbGJhY2sgdGhhdCB3aWxsIGJlXG4gKiAgICAgaW52b2tlZCBpZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCwgb3IgbnVsbC5cbiAqIEBwYXJhbSB7VEhJUz19IG9wdF9jb250ZXh0IEFuIG9wdGlvbmFsIGV4ZWN1dGlvbiBjb250ZXh0IGZvciB0aGUgY2FsbGJhY2tzLlxuICogICAgIGluIHRoZSBkZWZhdWx0IGNhbGxpbmcgY29udGV4dC5cbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9IFRoZSBjaGlsZCBQcm9taXNlLlxuICogQHRlbXBsYXRlIFJFU1VMVCxUSElTXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmFkZENoaWxkUHJvbWlzZV8gPSBmdW5jdGlvbihcbm9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvcHRfY29udGV4dCkge1xuXG4gIHZhciBjYWxsYmFja0VudHJ5ID0ge1xuICAgIGNoaWxkOiBudWxsLFxuICAgIG9uRnVsZmlsbGVkOiBudWxsLFxuICAgIG9uUmVqZWN0ZWQ6IG51bGxcbiAgfTtcblxuICBjYWxsYmFja0VudHJ5LmNoaWxkID0gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAvLyBJbnZva2Ugb25GdWxmaWxsZWQsIG9yIHJlc29sdmUgd2l0aCB0aGUgcGFyZW50J3MgdmFsdWUgaWYgYWJzZW50LlxuICAgIGNhbGxiYWNrRW50cnkub25GdWxmaWxsZWQgPSBvbkZ1bGZpbGxlZCA/IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gb25GdWxmaWxsZWQuY2FsbChvcHRfY29udGV4dCwgdmFsdWUpO1xuICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9XG4gICAgfSA6IHJlc29sdmU7XG5cbiAgICAvLyBJbnZva2Ugb25SZWplY3RlZCwgb3IgcmVqZWN0IHdpdGggdGhlIHBhcmVudCdzIHJlYXNvbiBpZiBhYnNlbnQuXG4gICAgY2FsbGJhY2tFbnRyeS5vblJlamVjdGVkID0gb25SZWplY3RlZCA/IGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG9uUmVqZWN0ZWQuY2FsbChvcHRfY29udGV4dCwgcmVhc29uKTtcbiAgICAgICAgaWYgKCFpc0RlZihyZXN1bHQpICYmIHJlYXNvbi5JU19DQU5DRUxMQVRJT05fRVJST1IpIHtcbiAgICAgICAgICAvLyBQcm9wYWdhdGUgY2FuY2VsbGF0aW9uIHRvIGNoaWxkcmVuIGlmIG5vIG90aGVyIHJlc3VsdCBpcyByZXR1cm5lZC5cbiAgICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgIH1cbiAgICB9IDogcmVqZWN0O1xuICB9KTtcblxuICBjYWxsYmFja0VudHJ5LmNoaWxkLnBhcmVudF8gPSB0aGlzO1xuICB0aGlzLmFkZENhbGxiYWNrRW50cnlfKFxuICAgIC8qKiBAdHlwZSB7Q2FuY2VsbGFibGVQcm9taXNlLkNhbGxiYWNrRW50cnlffSAqLyAoY2FsbGJhY2tFbnRyeSkpO1xuICByZXR1cm4gY2FsbGJhY2tFbnRyeS5jaGlsZDtcbn07XG5cblxuLyoqXG4gKiBVbmJsb2NrcyB0aGUgUHJvbWlzZSBhbmQgZnVsZmlsbHMgaXQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWUuXG4gKlxuICogQHBhcmFtIHtUWVBFfSB2YWx1ZVxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS51bmJsb2NrQW5kRnVsZmlsbF8gPSBmdW5jdGlvbih2YWx1ZSkge1xuICBpZiAodGhpcy5zdGF0ZV8gIT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uQkxPQ0tFRCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuY2VsbGFibGVQcm9taXNlIGlzIG5vdCBibG9ja2VkLicpO1xuICB9XG4gIHRoaXMuc3RhdGVfID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HO1xuICB0aGlzLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uRlVMRklMTEVELCB2YWx1ZSk7XG59O1xuXG5cbi8qKlxuICogVW5ibG9ja3MgdGhlIFByb21pc2UgYW5kIHJlamVjdHMgaXQgd2l0aCB0aGUgZ2l2ZW4gcmVqZWN0aW9uIHJlYXNvbi5cbiAqXG4gKiBAcGFyYW0geyp9IHJlYXNvblxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS51bmJsb2NrQW5kUmVqZWN0XyA9IGZ1bmN0aW9uKHJlYXNvbikge1xuICBpZiAodGhpcy5zdGF0ZV8gIT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uQkxPQ0tFRCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuY2VsbGFibGVQcm9taXNlIGlzIG5vdCBibG9ja2VkLicpO1xuICB9XG4gIHRoaXMuc3RhdGVfID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HO1xuICB0aGlzLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQsIHJlYXNvbik7XG59O1xuXG5cbi8qKlxuICogQXR0ZW1wdHMgdG8gcmVzb2x2ZSBhIFByb21pc2Ugd2l0aCBhIGdpdmVuIHJlc29sdXRpb24gc3RhdGUgYW5kIHZhbHVlLiBUaGlzXG4gKiBpcyBhIG5vLW9wIGlmIHRoZSBnaXZlbiBQcm9taXNlIGhhcyBhbHJlYWR5IGJlZW4gcmVzb2x2ZWQuXG4gKlxuICogSWYgdGhlIGdpdmVuIHJlc3VsdCBpcyBhIFRoZW5hYmxlIChzdWNoIGFzIGFub3RoZXIgUHJvbWlzZSksIHRoZSBQcm9taXNlIHdpbGxcbiAqIGJlIHJlc29sdmVkIHdpdGggdGhlIHNhbWUgc3RhdGUgYW5kIHJlc3VsdCBhcyB0aGUgVGhlbmFibGUgb25jZSBpdCBpcyBpdHNlbGZcbiAqIHJlc29sdmVkLlxuICpcbiAqIElmIHRoZSBnaXZlbiByZXN1bHQgaXMgbm90IGEgVGhlbmFibGUsIHRoZSBQcm9taXNlIHdpbGwgYmUgZnVsZmlsbGVkIG9yXG4gKiByZWplY3RlZCB3aXRoIHRoYXQgcmVzdWx0IGJhc2VkIG9uIHRoZSBnaXZlbiBzdGF0ZS5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9wcm9taXNlc2FwbHVzLmNvbS8jdGhlX3Byb21pc2VfcmVzb2x1dGlvbl9wcm9jZWR1cmVcbiAqXG4gKiBAcGFyYW0ge0NhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV99IHN0YXRlXG4gKiBAcGFyYW0geyp9IHggVGhlIHJlc3VsdCB0byBhcHBseSB0byB0aGUgUHJvbWlzZS5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUucmVzb2x2ZV8gPSBmdW5jdGlvbihzdGF0ZSwgeCkge1xuICBpZiAodGhpcy5zdGF0ZV8gIT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0aGlzID09PSB4KSB7XG4gICAgc3RhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVEO1xuICAgIHggPSBuZXcgVHlwZUVycm9yKCdDYW5jZWxsYWJsZVByb21pc2UgY2Fubm90IHJlc29sdmUgdG8gaXRzZWxmJyk7XG5cbiAgfSBlbHNlIGlmIChUaGVuYWJsZS5pc0ltcGxlbWVudGVkQnkoeCkpIHtcbiAgICB4ID0gLyoqIEB0eXBlIHshVGhlbmFibGV9ICovICh4KTtcbiAgICB0aGlzLnN0YXRlXyA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uQkxPQ0tFRDtcbiAgICB4LnRoZW4odGhpcy51bmJsb2NrQW5kRnVsZmlsbF8sIHRoaXMudW5ibG9ja0FuZFJlamVjdF8sIHRoaXMpO1xuICAgIHJldHVybjtcblxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KHgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciB0aGVuID0geC50aGVuO1xuICAgICAgaWYgKGlzRnVuY3Rpb24odGhlbikpIHtcbiAgICAgICAgdGhpcy50cnlUaGVuXyh4LCB0aGVuKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHN0YXRlID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRDtcbiAgICAgIHggPSBlO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMucmVzdWx0XyA9IHg7XG4gIHRoaXMuc3RhdGVfID0gc3RhdGU7XG4gIHRoaXMuc2NoZWR1bGVDYWxsYmFja3NfKCk7XG5cbiAgaWYgKHN0YXRlID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVEICYmICF4LklTX0NBTkNFTExBVElPTl9FUlJPUikge1xuICAgIENhbmNlbGxhYmxlUHJvbWlzZS5hZGRVbmhhbmRsZWRSZWplY3Rpb25fKHRoaXMsIHgpO1xuICB9XG59O1xuXG5cbi8qKlxuICogQXR0ZW1wdHMgdG8gY2FsbCB0aGUge0Bjb2RlIHRoZW59IG1ldGhvZCBvbiBhbiBvYmplY3QgaW4gdGhlIGhvcGVzIHRoYXQgaXQgaXNcbiAqIGEgUHJvbWlzZS1jb21wYXRpYmxlIGluc3RhbmNlLiBUaGlzIGFsbG93cyBpbnRlcm9wZXJhdGlvbiBiZXR3ZWVuIGRpZmZlcmVudFxuICogUHJvbWlzZSBpbXBsZW1lbnRhdGlvbnMsIGhvd2V2ZXIgYSBub24tY29tcGxpYW50IG9iamVjdCBtYXkgY2F1c2UgYSBQcm9taXNlXG4gKiB0byBoYW5nIGluZGVmaW5pdGVseS4gSWYgdGhlIHtAY29kZSB0aGVufSBtZXRob2QgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdGhlXG4gKiBkZXBlbmRlbnQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHRocm93biB2YWx1ZS5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNzBcbiAqXG4gKiBAcGFyYW0ge1RoZW5hYmxlfSB0aGVuYWJsZSBBbiBvYmplY3Qgd2l0aCBhIHtAY29kZSB0aGVufSBtZXRob2QgdGhhdCBtYXkgYmVcbiAqICAgICBjb21wYXRpYmxlIHdpdGggdGhlIFByb21pc2UvQSsgc3BlY2lmaWNhdGlvbi5cbiAqIEBwYXJhbSB7IUZ1bmN0aW9ufSB0aGVuIFRoZSB7QGNvZGUgdGhlbn0gbWV0aG9kIG9mIHRoZSBUaGVuYWJsZSBvYmplY3QuXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRyeVRoZW5fID0gZnVuY3Rpb24odGhlbmFibGUsIHRoZW4pIHtcbiAgdGhpcy5zdGF0ZV8gPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkJMT0NLRUQ7XG4gIHZhciBwcm9taXNlID0gdGhpcztcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuXG4gIHZhciByZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBpZiAoIWNhbGxlZCkge1xuICAgICAgY2FsbGVkID0gdHJ1ZTtcbiAgICAgIHByb21pc2UudW5ibG9ja0FuZEZ1bGZpbGxfKHZhbHVlKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIHJlamVjdCA9IGZ1bmN0aW9uKHJlYXNvbikge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgcHJvbWlzZS51bmJsb2NrQW5kUmVqZWN0XyhyZWFzb24pO1xuICAgIH1cbiAgfTtcblxuICB0cnkge1xuICAgIHRoZW4uY2FsbCh0aGVuYWJsZSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJlamVjdChlKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEV4ZWN1dGVzIHRoZSBwZW5kaW5nIGNhbGxiYWNrcyBvZiBhIHJlc29sdmVkIFByb21pc2UgYWZ0ZXIgYSB0aW1lb3V0LlxuICpcbiAqIFNlY3Rpb24gMi4yLjQgb2YgdGhlIFByb21pc2VzL0ErIHNwZWNpZmljYXRpb24gcmVxdWlyZXMgdGhhdCBQcm9taXNlXG4gKiBjYWxsYmFja3MgbXVzdCBvbmx5IGJlIGludm9rZWQgZnJvbSBhIGNhbGwgc3RhY2sgdGhhdCBvbmx5IGNvbnRhaW5zIFByb21pc2VcbiAqIGltcGxlbWVudGF0aW9uIGNvZGUsIHdoaWNoIHdlIGFjY29tcGxpc2ggYnkgaW52b2tpbmcgY2FsbGJhY2sgZXhlY3V0aW9uIGFmdGVyXG4gKiBhIHRpbWVvdXQuIElmIHtAY29kZSBzdGFydEV4ZWN1dGlvbl99IGlzIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyBmb3IgdGhlIHNhbWVcbiAqIFByb21pc2UsIHRoZSBjYWxsYmFjayBjaGFpbiB3aWxsIGJlIGV2YWx1YXRlZCBvbmx5IG9uY2UuIEFkZGl0aW9uYWwgY2FsbGJhY2tzXG4gKiBtYXkgYmUgYWRkZWQgZHVyaW5nIHRoZSBldmFsdWF0aW9uIHBoYXNlLCBhbmQgd2lsbCBiZSBleGVjdXRlZCBpbiB0aGUgc2FtZVxuICogZXZlbnQgbG9vcC5cbiAqXG4gKiBBbGwgUHJvbWlzZXMgYWRkZWQgdG8gdGhlIHdhaXRpbmcgbGlzdCBkdXJpbmcgdGhlIHNhbWUgYnJvd3NlciBldmVudCBsb29wXG4gKiB3aWxsIGJlIGV4ZWN1dGVkIGluIG9uZSBiYXRjaCB0byBhdm9pZCB1c2luZyBhIHNlcGFyYXRlIHRpbWVvdXQgcGVyIFByb21pc2UuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5zY2hlZHVsZUNhbGxiYWNrc18gPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLmV4ZWN1dGluZ18pIHtcbiAgICB0aGlzLmV4ZWN1dGluZ18gPSB0cnVlO1xuICAgIGFzeW5jLnJ1bih0aGlzLmV4ZWN1dGVDYWxsYmFja3NfLCB0aGlzKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEV4ZWN1dGVzIGFsbCBwZW5kaW5nIGNhbGxiYWNrcyBmb3IgdGhpcyBQcm9taXNlLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuZXhlY3V0ZUNhbGxiYWNrc18gPSBmdW5jdGlvbigpIHtcbiAgd2hpbGUgKHRoaXMuY2FsbGJhY2tFbnRyaWVzXyAmJiB0aGlzLmNhbGxiYWNrRW50cmllc18ubGVuZ3RoKSB7XG4gICAgdmFyIGVudHJpZXMgPSB0aGlzLmNhbGxiYWNrRW50cmllc187XG4gICAgdGhpcy5jYWxsYmFja0VudHJpZXNfID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVudHJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuZXhlY3V0ZUNhbGxiYWNrXyhlbnRyaWVzW2ldLCB0aGlzLnN0YXRlXywgdGhpcy5yZXN1bHRfKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5leGVjdXRpbmdfID0gZmFsc2U7XG59O1xuXG5cbi8qKlxuICogRXhlY3V0ZXMgYSBwZW5kaW5nIGNhbGxiYWNrIGZvciB0aGlzIFByb21pc2UuIEludm9rZXMgYW4ge0Bjb2RlIG9uRnVsZmlsbGVkfVxuICogb3Ige0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrIGJhc2VkIG9uIHRoZSByZXNvbHZlZCBzdGF0ZSBvZiB0aGUgUHJvbWlzZS5cbiAqXG4gKiBAcGFyYW0geyFDYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV99IGNhbGxiYWNrRW50cnkgQW4gZW50cnkgY29udGFpbmluZyB0aGVcbiAqICAgICBvbkZ1bGZpbGxlZCBhbmQvb3Igb25SZWplY3RlZCBjYWxsYmFja3MgZm9yIHRoaXMgc3RlcC5cbiAqIEBwYXJhbSB7Q2FuY2VsbGFibGVQcm9taXNlLlN0YXRlX30gc3RhdGUgVGhlIHJlc29sdXRpb24gc3RhdHVzIG9mIHRoZSBQcm9taXNlLFxuICogICAgIGVpdGhlciBGVUxGSUxMRUQgb3IgUkVKRUNURUQuXG4gKiBAcGFyYW0geyp9IHJlc3VsdCBUaGUgcmVzb2x2ZWQgcmVzdWx0IG9mIHRoZSBQcm9taXNlLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5leGVjdXRlQ2FsbGJhY2tfID0gZnVuY3Rpb24oXG5jYWxsYmFja0VudHJ5LCBzdGF0ZSwgcmVzdWx0KSB7XG4gIGlmIChzdGF0ZSA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5GVUxGSUxMRUQpIHtcbiAgICBjYWxsYmFja0VudHJ5Lm9uRnVsZmlsbGVkKHJlc3VsdCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZW1vdmVVbmhhbmRsZWRSZWplY3Rpb25fKCk7XG4gICAgY2FsbGJhY2tFbnRyeS5vblJlamVjdGVkKHJlc3VsdCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBNYXJrcyB0aGlzIHJlamVjdGVkIFByb21pc2UgYXMgaGF2aW5nIGJlaW5nIGhhbmRsZWQuIEFsc28gbWFya3MgYW55IHBhcmVudFxuICogUHJvbWlzZXMgaW4gdGhlIHJlamVjdGVkIHN0YXRlIGFzIGhhbmRsZWQuIFRoZSByZWplY3Rpb24gaGFuZGxlciB3aWxsIG5vXG4gKiBsb25nZXIgYmUgaW52b2tlZCBmb3IgdGhpcyBQcm9taXNlIChpZiBpdCBoYXMgbm90IGJlZW4gY2FsbGVkIGFscmVhZHkpLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUucmVtb3ZlVW5oYW5kbGVkUmVqZWN0aW9uXyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcDtcbiAgaWYgKENhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID4gMCkge1xuICAgIGZvciAocCA9IHRoaXM7IHAgJiYgcC51bmhhbmRsZWRSZWplY3Rpb25JZF87IHAgPSBwLnBhcmVudF8pIHtcbiAgICAgIGNsZWFyVGltZW91dChwLnVuaGFuZGxlZFJlamVjdGlvbklkXyk7XG4gICAgICBwLnVuaGFuZGxlZFJlamVjdGlvbklkXyA9IDA7XG4gICAgfVxuICB9IGVsc2UgaWYgKENhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID09PSAwKSB7XG4gICAgZm9yIChwID0gdGhpczsgcCAmJiBwLmhhZFVuaGFuZGxlZFJlamVjdGlvbl87IHAgPSBwLnBhcmVudF8pIHtcbiAgICAgIHAuaGFkVW5oYW5kbGVkUmVqZWN0aW9uXyA9IGZhbHNlO1xuICAgIH1cbiAgfVxufTtcblxuXG4vKipcbiAqIE1hcmtzIHRoaXMgcmVqZWN0ZWQgUHJvbWlzZSBhcyB1bmhhbmRsZWQuIElmIG5vIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFja1xuICogaXMgY2FsbGVkIGZvciB0aGlzIFByb21pc2UgYmVmb3JlIHRoZSB7QGNvZGUgVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWX1cbiAqIGV4cGlyZXMsIHRoZSByZWFzb24gd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHVuaGFuZGxlZCByZWplY3Rpb24gaGFuZGxlci4gVGhlXG4gKiBoYW5kbGVyIHR5cGljYWxseSByZXRocm93cyB0aGUgcmVqZWN0aW9uIHJlYXNvbiBzbyB0aGF0IGl0IGJlY29tZXMgdmlzaWJsZSBpblxuICogdGhlIGRldmVsb3BlciBjb25zb2xlLlxuICpcbiAqIEBwYXJhbSB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gcHJvbWlzZSBUaGUgcmVqZWN0ZWQgUHJvbWlzZS5cbiAqIEBwYXJhbSB7Kn0gcmVhc29uIFRoZSBQcm9taXNlIHJlamVjdGlvbiByZWFzb24uXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuYWRkVW5oYW5kbGVkUmVqZWN0aW9uXyA9IGZ1bmN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPiAwKSB7XG4gICAgcHJvbWlzZS51bmhhbmRsZWRSZWplY3Rpb25JZF8gPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgQ2FuY2VsbGFibGVQcm9taXNlLmhhbmRsZVJlamVjdGlvbl8uY2FsbChudWxsLCByZWFzb24pO1xuICAgIH0sIENhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZKTtcblxuICB9IGVsc2UgaWYgKENhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID09PSAwKSB7XG4gICAgcHJvbWlzZS5oYWRVbmhhbmRsZWRSZWplY3Rpb25fID0gdHJ1ZTtcbiAgICBhc3luYy5ydW4oZnVuY3Rpb24oKSB7XG4gICAgICBpZiAocHJvbWlzZS5oYWRVbmhhbmRsZWRSZWplY3Rpb25fKSB7XG4gICAgICAgIENhbmNlbGxhYmxlUHJvbWlzZS5oYW5kbGVSZWplY3Rpb25fLmNhbGwobnVsbCwgcmVhc29uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEEgbWV0aG9kIHRoYXQgaXMgaW52b2tlZCB3aXRoIHRoZSByZWplY3Rpb24gcmVhc29ucyBmb3IgUHJvbWlzZXMgdGhhdCBhcmVcbiAqIHJlamVjdGVkIGJ1dCBoYXZlIG5vIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFja3MgcmVnaXN0ZXJlZCB5ZXQuXG4gKiBAdHlwZSB7ZnVuY3Rpb24oKil9XG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXyA9IGFzeW5jLnRocm93RXhjZXB0aW9uO1xuXG5cbi8qKlxuICogU2V0cyBhIGhhbmRsZXIgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aXRoIHJlYXNvbnMgZnJvbSB1bmhhbmRsZWQgcmVqZWN0ZWRcbiAqIFByb21pc2VzLiBJZiB0aGUgcmVqZWN0ZWQgUHJvbWlzZSAob3Igb25lIG9mIGl0cyBkZXNjZW5kYW50cykgaGFzIGFuXG4gKiB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgcmVnaXN0ZXJlZCwgdGhlIHJlamVjdGlvbiB3aWxsIGJlIGNvbnNpZGVyZWRcbiAqIGhhbmRsZWQsIGFuZCB0aGUgcmVqZWN0aW9uIGhhbmRsZXIgd2lsbCBub3QgYmUgY2FsbGVkLlxuICpcbiAqIEJ5IGRlZmF1bHQsIHVuaGFuZGxlZCByZWplY3Rpb25zIGFyZSByZXRocm93biBzbyB0aGF0IHRoZSBlcnJvciBtYXkgYmVcbiAqIGNhcHR1cmVkIGJ5IHRoZSBkZXZlbG9wZXIgY29uc29sZSBvciBhIHtAY29kZSB3aW5kb3cub25lcnJvcn0gaGFuZGxlci5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCopfSBoYW5kbGVyIEEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aXRoIHJlYXNvbnMgZnJvbVxuICogICAgIHJlamVjdGVkIFByb21pc2VzLiBEZWZhdWx0cyB0byB7QGNvZGUgYXN5bmMudGhyb3dFeGNlcHRpb259LlxuICovXG5DYW5jZWxsYWJsZVByb21pc2Uuc2V0VW5oYW5kbGVkUmVqZWN0aW9uSGFuZGxlciA9IGZ1bmN0aW9uKGhhbmRsZXIpIHtcbiAgQ2FuY2VsbGFibGVQcm9taXNlLmhhbmRsZVJlamVjdGlvbl8gPSBoYW5kbGVyO1xufTtcblxuXG5cbi8qKlxuICogRXJyb3IgdXNlZCBhcyBhIHJlamVjdGlvbiByZWFzb24gZm9yIGNhbmNlbGVkIFByb21pc2VzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X21lc3NhZ2VcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMge0Vycm9yfVxuICogQGZpbmFsXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvciA9IGNsYXNzIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihvcHRfbWVzc2FnZSkge1xuICAgICBzdXBlcihvcHRfbWVzc2FnZSk7XG5cbiAgICAgaWYgKG9wdF9tZXNzYWdlKSB7XG4gICAgICAgdGhpcy5tZXNzYWdlID0gb3B0X21lc3NhZ2U7XG4gICAgIH1cbiAgIH1cbn07XG5cbi8qKiBAb3ZlcnJpZGUgKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvci5wcm90b3R5cGUubmFtZSA9ICdjYW5jZWwnO1xuXG5leHBvcnQge0NhbmNlbGxhYmxlUHJvbWlzZX07XG5leHBvcnQgZGVmYXVsdCBDYW5jZWxsYWJsZVByb21pc2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICAqIERlYm91bmNlcyBmdW5jdGlvbiBleGVjdXRpb24uXG4gICogQHBhcmFtIHshZnVuY3Rpb24oKX0gZm5cbiAgKiBAcGFyYW0ge251bWJlcn0gZGVsYXlcbiAgKiBAcmV0dXJuIHshZnVuY3Rpb24oKX1cbiAgKi9cbmZ1bmN0aW9uIGRlYm91bmNlKGZuLCBkZWxheSkge1xuXHRyZXR1cm4gZnVuY3Rpb24gZGVib3VuY2VkKCkge1xuXHRcdHZhciBhcmdzID0gYXJndW1lbnRzO1xuXHRcdGNhbmNlbERlYm91bmNlKGRlYm91bmNlZCk7XG5cdFx0ZGVib3VuY2VkLmlkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdGZuLmFwcGx5KG51bGwsIGFyZ3MpO1xuXHRcdH0sIGRlbGF5KTtcblx0fTtcbn1cblxuLyoqXG4gKiBDYW5jZWxzIHRoZSBzY2hlZHVsZWQgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjYW5jZWxEZWJvdW5jZShkZWJvdW5jZWQpIHtcblx0Y2xlYXJUaW1lb3V0KGRlYm91bmNlZC5pZCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRlYm91bmNlO1xuZXhwb3J0IHsgY2FuY2VsRGVib3VuY2UsIGRlYm91bmNlIH07XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBjb3JlIGZyb20gJ21ldGFsJztcblxuY29uc3QgUkVHRVggPSAvKFtcXC9dKT8oPzooPzpcXDooXFx3KykoPzpcXCgoKD86XFxcXC58W15cXFxcKCldKSopXFwpKT98XFwoKCg/OlxcXFwufFteXFxcXCgpXSkrKVxcKSkoWysqP10pPykvZztcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gYXJyYXkgb2YgcmVnZXggbWF0Y2hlcyB0byBhIG1vcmUgcmVhZGFibGUgb2JqZWN0IGZvcm1hdC5cbiAqIEBwYXJhbSB7IUFycmF5PHN0cmluZz59IG1hdGNoZXNcbiAqIEByZXR1cm4geyFPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRNYXRjaGVzVG9PYmoobWF0Y2hlcykge1xuXHRyZXR1cm4ge1xuXHRcdG1hdGNoOiBtYXRjaGVzWzBdLFxuXHRcdHByZWZpeDogbWF0Y2hlc1sxXSxcblx0XHRuYW1lOiBtYXRjaGVzWzJdLFxuXHRcdHBhcmFtUGF0dGVybjogbWF0Y2hlc1szXSxcblx0XHR1bm5hbWVkUGF0dGVybjogbWF0Y2hlc1s0XSxcblx0XHRtb2RpZmllcjogbWF0Y2hlc1s1XVxuXHR9O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiB0b2tlbnMgcGFyc2VkIGZyb20gYSByb3V0ZSBmb3JtYXQgc3RyaW5nIHRvIGEgcmVnZXguXG4gKiBAcGFyYW0geyFBcnJheTxzdHJpbmd8IU9iamVjdD59IHRva2Vuc1xuICogQHJldHVybiB7IVJlZ0V4cH1cbiAqL1xuZnVuY3Rpb24gY29udmVydFRva2Vuc1RvUmVnZXgodG9rZW5zKSB7XG5cdGxldCByZWdleCA9ICcnO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuXHRcdGlmIChjb3JlLmlzU3RyaW5nKHRva2Vuc1tpXSkpIHtcblx0XHRcdHJlZ2V4ICs9IGVzY2FwZSh0b2tlbnNbaV0pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRsZXQgY2FwdHVyZSA9IGVuY2xvc2VOb25DYXB0dXJpbmdHcm91cCh0b2tlbnNbaV0ucGF0dGVybik7XG5cdFx0XHRpZiAodG9rZW5zW2ldLnJlcGVhdCkge1xuXHRcdFx0XHRjYXB0dXJlICs9IGVuY2xvc2VOb25DYXB0dXJpbmdHcm91cCgnXFxcXC8nICsgY2FwdHVyZSkgKyAnKic7XG5cdFx0XHR9XG5cdFx0XHRjYXB0dXJlID0gZXNjYXBlKHRva2Vuc1tpXS5wcmVmaXgpICsgYCgke2NhcHR1cmV9KWA7XG5cdFx0XHRpZiAodG9rZW5zW2ldLm9wdGlvbmFsKSB7XG5cdFx0XHRcdGlmICghdG9rZW5zW2ldLnBhcnRpYWwpIHtcblx0XHRcdFx0XHRjYXB0dXJlID0gZW5jbG9zZU5vbkNhcHR1cmluZ0dyb3VwKGNhcHR1cmUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNhcHR1cmUgKz0gJz8nO1xuXHRcdFx0fVxuXHRcdFx0cmVnZXggKz0gY2FwdHVyZTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIG5ldyBSZWdFeHAoJ14nICsgbWFrZVRyYWlsaW5nU2xhc2hPcHRpb25hbChyZWdleCkgKyAnJCcpO1xufVxuXG4vKipcbiAqIEVuY2xvc2VzIHRoZSBnaXZlbiByZWdleCBwYXR0ZXJuIGludG8gYSBub24gY2FwdHVyaW5nIGdyb3VwLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdHRlcm5cbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZW5jbG9zZU5vbkNhcHR1cmluZ0dyb3VwKHBhdHRlcm4pIHtcblx0cmV0dXJuIGAoPzoke3BhdHRlcm59KWA7XG59XG5cbi8qKlxuICogRXNjYXBlcyB0aGUgZ2l2ZW4gc3RyaW5nIHRvIHNob3cgdXAgaW4gdGhlIHBhdGggcmVnZXguXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVzY2FwZShzdHIpIHtcblx0cmV0dXJuIHN0ci5yZXBsYWNlKC8oWy4rKj89XiE6JHt9KClbXFxdfFxcL1xcXFxdKS9nLCAnXFxcXCQxJyk7XG59XG5cbi8qKlxuICogTWFrZXMgdHJhaWxpbmcgc2xhc2ggb3B0aW9uYWwgb24gcGF0aHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVnZXhcbiAqIEBwYXJhbSB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBtYWtlVHJhaWxpbmdTbGFzaE9wdGlvbmFsKHJlZ2V4KSB7XG5cdGlmICgvXFwvJC8udGVzdChyZWdleCkpIHtcblx0XHRyZWdleCArPSAnPyc7XG5cdH0gZWxzZSB7XG5cdFx0cmVnZXggKz0gJ1xcXFwvPyc7XG5cdH1cblx0cmV0dXJuIHJlZ2V4O1xufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgZ2l2ZW4gcm91dGUgZm9ybWF0IHN0cmluZyBpbnRvIHRva2VucyByZXByZXNlbnRpbmcgaXRzIGNvbnRlbnRzLlxuICogQHBhcmFtIHshQXJyYXl8c3RyaW5nfSByb3V0ZU9yVG9rZW5zIEVpdGhlciBhIHJvdXRlIGZvcm1hdCBzdHJpbmcgb3IgdG9rZW5zXG4gKiAgICAgcHJldmlvdXNseSBwYXJzZWQgdmlhIHRoZSBgcGFyc2VgIGZ1bmN0aW9uLlxuICogQHJldHVybiB7IUFycmF5PHN0cmluZ3whT2JqZWN0Pn0gQW4gYXJyYXkgb2YgdG9rZW5zIHRoYXQgY2FuIGJlIGVpdGhlciBwbGFpblxuICogICAgIHN0cmluZ3MgKHBhcnQgb2YgdGhlIHJvdXRlKSBvciBvYmplY3RzIGNvbnRhaW5pbmcgaW5mb3JtYXRpb25zIG9uIHBhcmFtcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlKHJvdXRlT3JUb2tlbnMpIHtcblx0aWYgKCFjb3JlLmlzU3RyaW5nKHJvdXRlT3JUb2tlbnMpKSB7XG5cdFx0cmV0dXJuIHJvdXRlT3JUb2tlbnM7XG5cdH1cblxuXHRjb25zdCByb3V0ZSA9IHJvdXRlT3JUb2tlbnM7XG5cdGxldCB1bm5hbWVkQ291bnQgPSAwO1xuXHRjb25zdCB0b2tlbnMgPSBbXTtcblx0bGV0IGN1cnJQYXRoID0gJyc7XG5cdGxldCBpbmRleCA9IDA7XG5cblx0bGV0IG1hdGNoZXMgPSBSRUdFWC5leGVjKHJvdXRlKTtcblx0d2hpbGUgKG1hdGNoZXMpIHtcblx0XHRjb25zdCBkYXRhID0gY29udmVydE1hdGNoZXNUb09iaihtYXRjaGVzKTtcblxuXHRcdGN1cnJQYXRoID0gcm91dGUuc2xpY2UoaW5kZXgsIG1hdGNoZXMuaW5kZXgpO1xuXHRcdGluZGV4ID0gbWF0Y2hlcy5pbmRleCArIGRhdGEubWF0Y2gubGVuZ3RoO1xuXHRcdHRva2Vucy5wdXNoKGN1cnJQYXRoKTtcblxuXHRcdHRva2Vucy5wdXNoKHtcblx0XHRcdG5hbWU6IGRhdGEubmFtZSA/IGRhdGEubmFtZSA6ICcnICsgdW5uYW1lZENvdW50KyssXG5cdFx0XHRwYXJ0aWFsOiByb3V0ZVtpbmRleF0gJiYgcm91dGVbaW5kZXhdICE9PSBkYXRhLnByZWZpeCxcblx0XHRcdHByZWZpeDogZGF0YS5wcmVmaXggfHwgJycsXG5cdFx0XHRwYXR0ZXJuOiBkYXRhLnBhcmFtUGF0dGVybiB8fCBkYXRhLnVubmFtZWRQYXR0ZXJuIHx8ICdbXlxcXFwvXSsnLFxuXHRcdFx0cmVwZWF0OiBkYXRhLm1vZGlmaWVyID09PSAnKicgfHwgZGF0YS5tb2RpZmllciA9PT0gJysnLFxuXHRcdFx0b3B0aW9uYWw6IGRhdGEubW9kaWZpZXIgPT09ICcqJyB8fCBkYXRhLm1vZGlmaWVyID09PSAnPydcblx0XHR9KTtcblxuXHRcdG1hdGNoZXMgPSBSRUdFWC5leGVjKHJvdXRlKTtcblx0fVxuXG5cdGlmIChpbmRleCA8IHJvdXRlLmxlbmd0aCkge1xuXHRcdHRva2Vucy5wdXNoKHJvdXRlLnN1YnN0cihpbmRleCkpO1xuXHR9XG5cdHJldHVybiB0b2tlbnM7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIHJvdXRlIGZvcm1hdCBzdHJpbmcgdG8gYSByZWdleCB0aGF0IGNhbiBleHRyYWN0IHBhcmFtXG4gKiBkYXRhIGZyb20gcGF0aHMgbWF0Y2hpbmcgaXQuXG4gKiBAcGFyYW0geyFBcnJheXxzdHJpbmd9IHJvdXRlT3JUb2tlbnMgRWl0aGVyIGEgcm91dGUgZm9ybWF0IHN0cmluZyBvciB0b2tlbnNcbiAqICAgICBwcmV2aW91c2x5IHBhcnNlZCB2aWEgdGhlIGBwYXJzZWAgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHshUmVnRXhwfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9SZWdleChyb3V0ZU9yVG9rZW5zKSB7XG5cdHJldHVybiBjb252ZXJ0VG9rZW5zVG9SZWdleChwYXJzZShyb3V0ZU9yVG9rZW5zKSk7XG59XG5cbi8qKlxuICogRXh0cmFjdHMgZGF0YSBmcm9tIHRoZSBnaXZlbiBwYXRoIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIHJvdXRlIGZvcm1hdC5cbiAqIEBwYXJhbSB7IUFycmF5fHN0cmluZ30gcm91dGVPclRva2VucyBFaXRoZXIgYSByb3V0ZSBmb3JtYXQgc3RyaW5nIG9yIHRva2Vuc1xuICogICAgIHByZXZpb3VzbHkgcGFyc2VkIHZpYSB0aGUgYHBhcnNlYCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBUaGUgcGF0aCB0byBleHRyYWN0IHBhcmFtIGRhdGEgZnJvbS5cbiAqIEByZXR1cm4ge09iamVjdDxzdHJpbmcsIHN0cmluZz59IFRoZSBkYXRhIG9iamVjdCwgb3IgbnVsbCBpZiB0aGUgcGF0aCBkb2Vzbid0XG4gKiAgICAgbWF0Y2ggdGhlIGdpdmVuIGZvcm1hdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3REYXRhKHJvdXRlT3JUb2tlbnMsIHBhdGgpIHtcblx0Y29uc3QgZGF0YSA9IHt9O1xuXHRjb25zdCB0b2tlbnMgPSBwYXJzZShyb3V0ZU9yVG9rZW5zKTtcblx0Y29uc3QgbWF0Y2ggPSBwYXRoLm1hdGNoKGNvbnZlcnRUb2tlbnNUb1JlZ2V4KHRva2VucykpO1xuXG5cdGlmICghbWF0Y2gpIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdGxldCBwYXJhbUluZGV4ID0gMTtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoIWNvcmUuaXNTdHJpbmcodG9rZW5zW2ldKSkge1xuXHRcdFx0bGV0IHZhbHVlID0gbWF0Y2hbcGFyYW1JbmRleCsrXTtcblx0XHRcdGlmIChjb3JlLmlzRGVmKHZhbHVlKSkge1xuXHRcdFx0XHRpZiAodG9rZW5zW2ldLnJlcGVhdCkge1xuXHRcdFx0XHRcdHZhbHVlID0gdmFsdWUuc3BsaXQoJy8nKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhW3Rva2Vuc1tpXS5uYW1lXSA9IHZhbHVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gZGF0YTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgaXNEZWZBbmROb3ROdWxsLCBpc0Z1bmN0aW9uLCBpc1N0cmluZyB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IGV4dHJhY3REYXRhLCBwYXJzZSwgdG9SZWdleCB9IGZyb20gJ21ldGFsLXBhdGgtcGFyc2VyJztcblxuY2xhc3MgUm91dGUge1xuXG5cdC8qKlxuXHQgKiBSb3V0ZSBjbGFzcy5cblx0ICogQHBhcmFtIHshc3RyaW5nfFJlZ0V4cHxGdW5jdGlvbn0gcGF0aFxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gaGFuZGxlclxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKHBhdGgsIGhhbmRsZXIpIHtcblx0XHRpZiAoIWlzRGVmQW5kTm90TnVsbChwYXRoKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdSb3V0ZSBwYXRoIG5vdCBzcGVjaWZpZWQuJyk7XG5cdFx0fVxuXHRcdGlmICghaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdSb3V0ZSBoYW5kbGVyIGlzIG5vdCBhIGZ1bmN0aW9uLicpO1xuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIERlZmluZXMgdGhlIGhhbmRsZXIgd2hpY2ggd2lsbCBleGVjdXRlIG9uY2UgYSBVUkwgaW4gdGhlIGFwcGxpY2F0aW9uXG5cdFx0ICogbWF0Y2hlcyB0aGUgcGF0aC5cblx0XHQgKiBAdHlwZSB7IUZ1bmN0aW9ufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmhhbmRsZXIgPSBoYW5kbGVyO1xuXG5cdFx0LyoqXG5cdFx0ICogRGVmaW5lcyB0aGUgcGF0aCB3aGljaCB3aWxsIHRyaWdnZXIgdGhlIHJvdXRlIGhhbmRsZXIuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd8UmVnRXhwfEZ1bmN0aW9ufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBhdGggPSBwYXRoO1xuXHR9XG5cblx0LyoqXG5cdCogQnVpbGRzIHBhcnNlZCBkYXRhIChyZWdleCBhbmQgdG9rZW5zKSBmb3IgdGhpcyByb3V0ZS5cblx0KiBAcmV0dXJuIHshT2JqZWN0fVxuXHQqIEBwcm90ZWN0ZWRcblx0Ki9cblx0YnVpbGRQYXJzZWREYXRhXygpIHtcblx0XHRpZiAoIXRoaXMucGFyc2VkRGF0YV8pIHtcblx0XHRcdHZhciB0b2tlbnMgPSBwYXJzZSh0aGlzLnBhdGgpO1xuXHRcdFx0dmFyIHJlZ2V4ID0gdG9SZWdleCh0b2tlbnMpO1xuXHRcdFx0dGhpcy5wYXJzZWREYXRhXyA9IHtcblx0XHRcdFx0cmVnZXgsXG5cdFx0XHRcdHRva2Vuc1xuXHRcdFx0fTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMucGFyc2VkRGF0YV87XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgcGFyYW0gZGF0YSBmcm9tIHRoZSBnaXZlbiBwYXRoLCBhY2NvcmRpbmcgdG8gdGhpcyByb3V0ZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHVybCBwYXRoIHRvIGV4dHJhY3QgcGFyYW1zIGZyb20uXG5cdCAqIEByZXR1cm4ge09iamVjdH0gVGhlIGV4dHJhY3RlZCBkYXRhLCBpZiB0aGUgcGF0aCBtYXRjaGVzIHRoaXMgcm91dGUsIG9yXG5cdCAqICAgICBudWxsIG90aGVyd2lzZS5cblx0ICovXG5cdGV4dHJhY3RQYXJhbXMocGF0aCkge1xuXHRcdGlmIChpc1N0cmluZyh0aGlzLnBhdGgpKSB7XG5cdFx0XHRyZXR1cm4gZXh0cmFjdERhdGEodGhpcy5idWlsZFBhcnNlZERhdGFfKCkudG9rZW5zLCBwYXRoKTtcblx0XHR9XG5cdFx0cmV0dXJuIHt9O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHJvdXRlIGhhbmRsZXIuXG5cdCAqIEByZXR1cm4geyFGdW5jdGlvbn1cblx0ICovXG5cdGdldEhhbmRsZXIoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaGFuZGxlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSByb3V0ZSBwYXRoLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfFJlZ0V4cHxGdW5jdGlvbn1cblx0ICovXG5cdGdldFBhdGgoKSB7XG5cdFx0cmV0dXJuIHRoaXMucGF0aDtcblx0fVxuXG5cdC8qKlxuIFx0ICogTWF0Y2hlcyBpZiB0aGUgcm91dGVyIGNhbiBoYW5kbGUgdGhlIHRlc3RlZCBwYXRoLlxuIFx0ICogQHBhcmFtIHshc3RyaW5nfSB2YWx1ZSBQYXRoIHRvIHRlc3QgKG1heSBjb250YWluIHRoZSBxdWVyeXN0cmluZyBwYXJ0KS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIG1hdGNoZXMgYW55IHJvdXRlLlxuXHQgKi9cblx0bWF0Y2hlc1BhdGgodmFsdWUpIHtcblx0XHR2YXIgcGF0aCA9IHRoaXMucGF0aDtcblxuXHRcdGlmIChpc0Z1bmN0aW9uKHBhdGgpKSB7XG5cdFx0XHRyZXR1cm4gcGF0aCh2YWx1ZSk7XG5cdFx0fVxuXHRcdGlmIChpc1N0cmluZyhwYXRoKSkge1xuXHRcdFx0cGF0aCA9IHRoaXMuYnVpbGRQYXJzZWREYXRhXygpLnJlZ2V4O1xuXHRcdH1cblx0XHRpZiAocGF0aCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuXHRcdFx0cmV0dXJuIHZhbHVlLnNlYXJjaChwYXRoKSA+IC0xO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IFJvdXRlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBEaXNwb3NhYmxlIH0gZnJvbSAnbWV0YWwnO1xuXG5jbGFzcyBDYWNoZWFibGUgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblxuXHQvKipcblx0ICogQWJzdHJhY3QgY2xhc3MgZm9yIGRlZmluaW5nIGNhY2hlYWJsZSBiZWhhdmlvci5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGNhY2hlZCBkYXRhLlxuXHRcdCAqIEB0eXBlIHshT2JqZWN0fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5jYWNoZSA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB3aGV0aGVyIGNsYXNzIGlzIGNhY2hlYWJsZS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCBmYWxzZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmNhY2hlYWJsZSA9IGZhbHNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgY29udGVudCB0byB0aGUgY2FjaGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50IENvbnRlbnQgdG8gYmUgY2FjaGVkLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRhZGRDYWNoZShjb250ZW50KSB7XG5cdFx0aWYgKHRoaXMuY2FjaGVhYmxlKSB7XG5cdFx0XHR0aGlzLmNhY2hlID0gY29udGVudDtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQ2xlYXJzIHRoZSBjYWNoZS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0Y2xlYXJDYWNoZSgpIHtcblx0XHR0aGlzLmNhY2hlID0gbnVsbDtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBvZiB0aGlzIGluc3RhbmNlJ3Mgb2JqZWN0IHJlZmVyZW5jZXMuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMuY2xlYXJDYWNoZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNhY2hlZCBjb250ZW50LlxuXHQgKiBAcmV0dXJuIHtPYmplY3R9IENhY2hlZCBjb250ZW50LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRnZXRDYWNoZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5jYWNoZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBXaGV0aGVyIHRoZSBjbGFzcyBpcyBjYWNoZWFibGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFJldHVybnMgdHJ1ZSB3aGVuIGNsYXNzIGlzIGNhY2hlYWJsZSwgZmFsc2Ugb3RoZXJ3aXNlLlxuXHQgKi9cblx0aXNDYWNoZWFibGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuY2FjaGVhYmxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgd2hldGhlciB0aGUgY2xhc3MgaXMgY2FjaGVhYmxlLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGNhY2hlYWJsZVxuXHQgKi9cblx0c2V0Q2FjaGVhYmxlKGNhY2hlYWJsZSkge1xuXHRcdGlmICghY2FjaGVhYmxlKSB7XG5cdFx0XHR0aGlzLmNsZWFyQ2FjaGUoKTtcblx0XHR9XG5cdFx0dGhpcy5jYWNoZWFibGUgPSBjYWNoZWFibGU7XG5cdH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBDYWNoZWFibGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IGdsb2JhbEV2YWwgfSBmcm9tICdtZXRhbC1kb20nO1xuaW1wb3J0IENhY2hlYWJsZSBmcm9tICcuLi9jYWNoZWFibGUvQ2FjaGVhYmxlJztcbmltcG9ydCBDYW5jZWxsYWJsZVByb21pc2UgZnJvbSAnbWV0YWwtcHJvbWlzZSc7XG5cbmNsYXNzIFNjcmVlbiBleHRlbmRzIENhY2hlYWJsZSB7XG5cblx0LyoqXG5cdCAqIFNjcmVlbiBjbGFzcyBpcyBhIHNwZWNpYWwgdHlwZSBvZiByb3V0ZSBoYW5kbGVyIHRoYXQgcHJvdmlkZXMgaGVscGVyXG5cdCAqIHV0aWxpdGllcyB0aGF0IGFkZHMgbGlmZWN5Y2xlIGFuZCBtZXRob2RzIHRvIHByb3ZpZGUgY29udGVudCB0byBlYWNoXG5cdCAqIHJlZ2lzdGVyZWQgc3VyZmFjZS5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqIEBleHRlbmRzIHtDYWNoZWFibGV9XG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHNjcmVlbiBpZC5cblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmlkID0gdGhpcy5tYWtlSWRfKGdldFVpZCgpKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBzY3JlZW4gbWV0YSB0YWdzLiBSZWxldmFudCB3aGVuIHRoZSBtZXRhIHRhZ3Ncblx0XHQgKiBzaG91bGQgYmUgdXBkYXRlZCB3aGVuIHNjcmVlbiBpcyByZW5kZXJlZC5cblx0XHQgKi9cblx0XHR0aGlzLm1ldGFzID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBzY3JlZW4gdGl0bGUuIFJlbGV2YW50IHdoZW4gdGhlIHBhZ2UgdGl0bGUgc2hvdWxkIGJlXG5cdFx0ICogdXBhZGF0ZWQgd2hlbiBzY3JlZW4gaXMgcmVuZGVyZWQuXG5cdFx0ICogQHR5cGUgez9zdHJpbmc9fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy50aXRsZSA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogRmlyZXMgd2hlbiB0aGUgc2NyZWVuIGlzIGFjdGl2ZS4gQWxsb3dzIGEgc2NyZWVuIHRvIHBlcmZvcm0gYW55IHNldHVwXG5cdCAqIHRoYXQgcmVxdWlyZXMgaXRzIERPTSB0byBiZSB2aXNpYmxlLiBMaWZlY3ljbGUuXG5cdCAqL1xuXHRhY3RpdmF0ZSgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGFjdGl2YXRlJyk7XG5cdH1cblxuXHQvKipcblx0ICogR2l2ZXMgdGhlIFNjcmVlbiBhIGNoYW5jZSB0byBjYW5jZWwgdGhlIG5hdmlnYXRpb24gYW5kIHN0b3AgaXRzZWxmIGZyb21cblx0ICogYWN0aXZhdGluZy4gQ2FuIGJlIHVzZWQsIGZvciBleGFtcGxlLCB0byBwcmV2ZW50IG5hdmlnYXRpb24gaWYgYSB1c2VyXG5cdCAqIGlzIG5vdCBhdXRoZW50aWNhdGVkLiBMaWZlY3ljbGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW49fD9DYW5jZWxsYWJsZVByb21pc2U9fSBJZiByZXR1cm5zIG9yIHJlc29sdmVzIHRvIHRydWUsXG5cdCAqICAgICB0aGUgY3VycmVudCBzY3JlZW4gaXMgbG9ja2VkIGFuZCB0aGUgbmV4dCBuYWdpdmF0aW9uIGludGVycnVwdGVkLlxuXHQgKi9cblx0YmVmb3JlQWN0aXZhdGUoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBiZWZvcmVBY3RpdmF0ZScpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdpdmVzIHRoZSBTY3JlZW4gYSBjaGFuY2UgdG8gY2FuY2VsIHRoZSBuYXZpZ2F0aW9uIGFuZCBzdG9wIGl0c2VsZiBmcm9tXG5cdCAqIGJlaW5nIGRlYWN0aXZhdGVkLiBDYW4gYmUgdXNlZCwgZm9yIGV4YW1wbGUsIGlmIHRoZSBzY3JlZW4gaGFzIHVuc2F2ZWRcblx0ICogc3RhdGUuIExpZmVjeWNsZS4gQ2xlYW4tdXAgc2hvdWxkIG5vdCBiZSBwcmVmb3JtZWQgaGVyZSwgc2luY2UgdGhlXG5cdCAqIG5hdmlnYXRpb24gbWF5IHN0aWxsIGJlIGNhbmNlbGxlZC4gRG8gY2xlYW4tdXAgaW4gZGVhY3RpdmF0ZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbj18P0NhbmNlbGxhYmxlUHJvbWlzZT19IElmIHJldHVybnMgb3IgcmVzb2x2ZXMgdG8gdHJ1ZSxcblx0ICogICAgIHRoZSBjdXJyZW50IHNjcmVlbiBpcyBsb2NrZWQgYW5kIHRoZSBuZXh0IG5hZ2l2YXRpb24gaW50ZXJydXB0ZWQuXG5cdCAqL1xuXHRiZWZvcmVEZWFjdGl2YXRlKCkge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gYmVmb3JlRGVhY3RpdmF0ZScpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdpdmVzIHRoZSBTY3JlZW4gYSBjaGFuY2UgZm9ybWF0IHRoZSBwYXRoIGJlZm9yZSBoaXN0b3J5IHVwZGF0ZS5cblx0ICogQHBhdGggeyFzdHJpbmd9IHBhdGggTmF2aWdhdGlvbiBwYXRoLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfSBOYXZpZ2F0aW9uIHBhdGggdG8gdXNlIG9uIGhpc3RvcnkuXG5cdCAqL1xuXHRiZWZvcmVVcGRhdGVIaXN0b3J5UGF0aChwYXRoKSB7XG5cdFx0cmV0dXJuIHBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogR2l2ZXMgdGhlIFNjcmVlbiBhIGNoYW5jZSBmb3JtYXQgdGhlIHN0YXRlIGJlZm9yZSBoaXN0b3J5IHVwZGF0ZS5cblx0ICogQHBhdGggeyFvYmplY3R9IHN0YXRlIEhpc3Rvcnkgc3RhdGUuXG5cdCAqIEByZXR1cm4geyFvYmplY3R9IEhpc3Rvcnkgc3RhdGUgdG8gdXNlIG9uIGhpc3RvcnkuXG5cdCAqL1xuXHRiZWZvcmVVcGRhdGVIaXN0b3J5U3RhdGUoc3RhdGUpIHtcblx0XHRyZXR1cm4gc3RhdGU7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb3dzIGEgc2NyZWVuIHRvIGRvIGFueSBjbGVhbnVwIG5lY2Vzc2FyeSBhZnRlciBpdCBoYXMgYmVlblxuXHQgKiBkZWFjdGl2YXRlZCwgZm9yIGV4YW1wbGUgY2FuY2VsbGluZyBvdXRzdGFuZGluZyByZXF1ZXN0cyBvciBzdG9wcGluZ1xuXHQgKiB0aW1lcnMuIExpZmVjeWNsZS5cblx0ICovXG5cdGRlYWN0aXZhdGUoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBkZWFjdGl2YXRlJyk7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZSBhIHNjcmVlbiwgZWl0aGVyIGFmdGVyIGl0IGlzIGRlYWN0aXZhdGVkIChpbiB0aGUgY2FzZSBvZiBhXG5cdCAqIG5vbi1jYWNoZWFibGUgdmlldykgb3Igd2hlbiB0aGUgQXBwIGlzIGl0c2VsZiBkaXNwb3NlZCBmb3Igd2hhdGV2ZXJcblx0ICogcmVhc29uLiBMaWZlY3ljbGUuXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0c3VwZXIuZGlzcG9zZUludGVybmFsKCk7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBkaXNwb3NlJyk7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb3dzIGEgc2NyZWVuIHRvIGV2YWx1YXRlIHNjcmlwdHMgYmVmb3JlIHRoZSBlbGVtZW50IGlzIG1hZGUgdmlzaWJsZS5cblx0ICogTGlmZWN5Y2xlLlxuXHQgKiBAcGFyYW0geyFvYmplY3R9IHN1cmZhY2VzIE1hcCBvZiBzdXJmYWNlcyB0byBmbGlwIGtleWVkIGJ5IHN1cmZhY2UgaWQuXG5cdCAqIEByZXR1cm4gez9DYW5jZWxsYWJsZVByb21pc2U9fSBUaGlzIGNhbiByZXR1cm4gYSBwcm9taXNlLCB3aGljaCB3aWxsXG5cdCAqICAgICBwYXVzZSB0aGUgbmF2aWdhdGlvbiB1bnRpbCBpdCBpcyByZXNvbHZlZC5cblx0ICovXG5cdGV2YWx1YXRlU2NyaXB0cyhzdXJmYWNlcykge1xuXHRcdE9iamVjdC5rZXlzKHN1cmZhY2VzKS5mb3JFYWNoKHNJZCA9PiB7XG5cdFx0XHRpZiAoc3VyZmFjZXNbc0lkXS5hY3RpdmVDaGlsZCkge1xuXHRcdFx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdHNJbkVsZW1lbnQoc3VyZmFjZXNbc0lkXS5hY3RpdmVDaGlsZCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKCk7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb3dzIGEgc2NyZWVuIHRvIGV2YWx1YXRlIHN0eWxlcyBiZWZvcmUgdGhlIGVsZW1lbnQgaXMgbWFkZSB2aXNpYmxlLlxuXHQgKiBMaWZlY3ljbGUuXG5cdCAqIEBwYXJhbSB7IW9iamVjdH0gc3VyZmFjZXMgTWFwIG9mIHN1cmZhY2VzIHRvIGZsaXAga2V5ZWQgYnkgc3VyZmFjZSBpZC5cblx0ICogQHJldHVybiB7P0NhbmNlbGxhYmxlUHJvbWlzZT19IFRoaXMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIHdpbGxcblx0ICogICAgIHBhdXNlIHRoZSBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0ZXZhbHVhdGVTdHlsZXMoKSB7XG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKCk7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb3dzIGEgc2NyZWVuIHRvIHBlcmZvcm0gYW55IHNldHVwIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZWxlbWVudCBpc1xuXHQgKiBtYWRlIHZpc2libGUuIExpZmVjeWNsZS5cblx0ICogQHBhcmFtIHshb2JqZWN0fSBzdXJmYWNlcyBNYXAgb2Ygc3VyZmFjZXMgdG8gZmxpcCBrZXllZCBieSBzdXJmYWNlIGlkLlxuXHQgKiBAcmV0dXJuIHs/Q2FuY2VsbGFibGVQcm9taXNlPX0gVGhpcyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggd2lsbCBwYXVzZSB0aGVcblx0ICogICAgIG5hdmlnYXRpb24gdW50aWwgaXQgaXMgcmVzb2x2ZWQuXG5cdCAqL1xuXHRmbGlwKHN1cmZhY2VzKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBmbGlwJyk7XG5cblx0XHR2YXIgdHJhbnNpdGlvbnMgPSBbXTtcblxuXHRcdE9iamVjdC5rZXlzKHN1cmZhY2VzKS5mb3JFYWNoKHNJZCA9PiB7XG5cdFx0XHR2YXIgc3VyZmFjZSA9IHN1cmZhY2VzW3NJZF07XG5cdFx0XHR2YXIgZGVmZXJyZWQgPSBzdXJmYWNlLnNob3codGhpcy5pZCk7XG5cdFx0XHR0cmFuc2l0aW9ucy5wdXNoKGRlZmVycmVkKTtcblx0XHR9KTtcblxuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UuYWxsKHRyYW5zaXRpb25zKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzY3JlZW4gaWQuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldElkKCkge1xuXHRcdHJldHVybiB0aGlzLmlkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHNjcmVlbiBtZXRhIHRhZ3MuXG5cdCAqIEByZXR1cm4ge05vZGVMaXN0fE5vZGV9XG5cdCAqL1xuXHRnZXRNZXRhcygpIHtcblx0XHRyZXR1cm4gdGhpcy5tZXRhcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBjb250ZW50IGZvciB0aGUgZ2l2ZW4gc3VyZmFjZSwgb3IgbnVsbCBpZiB0aGUgc3VyZmFjZSBpc24ndFxuXHQgKiB1c2VkIGJ5IHRoaXMgc2NyZWVuLiBUaGlzIHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBzY3JlZW4gaXMgaW5pdGlhbGx5XG5cdCAqIGNvbnN0cnVjdGVkIG9yLCBpZiBhIHNjcmVlbiBpcyBub24tY2FjaGVhYmxlLCB3aGVuIG5hdmlnYXRlZC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzdXJmYWNlSWQgVGhlIGlkIG9mIHRoZSBzdXJmYWNlIERPTSBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IHBhcmFtcyBQYXJhbXMgZXh0cmFjdGVkIGZyb20gdGhlIGN1cnJlbnQgcGF0aC5cblx0ICogQHJldHVybiB7P3N0cmluZ3xFbGVtZW50PX0gVGhpcyBjYW4gcmV0dXJuIGEgc3RyaW5nIG9yIG5vZGUgcmVwcmVzZW50aW5nXG5cdCAqICAgICB0aGUgY29udGVudCBvZiB0aGUgc3VyZmFjZS4gSWYgcmV0dXJucyBmYWxzeSB2YWx1ZXMgc3VyZmFjZSBkZWZhdWx0XG5cdCAqICAgICBjb250ZW50IGlzIHJlc3RvcmVkLlxuXHQgKi9cblx0Z2V0U3VyZmFjZUNvbnRlbnQoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBnZXRTdXJmYWNlQ29udGVudCcpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHNjcmVlbiB0aXRsZS5cblx0ICogQHJldHVybiB7P3N0cmluZz19XG5cdCAqL1xuXHRnZXRUaXRsZSgpIHtcblx0XHRyZXR1cm4gdGhpcy50aXRsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGFsbCBjb250ZW50cyBmb3IgdGhlIHN1cmZhY2VzLiBUaGlzIHdpbGwgcGFzcyB0aGUgbG9hZGVkIGNvbnRlbnRcblx0ICogdG8gPGNvZGU+U2NyZWVuLmxvYWQ8L2NvZGU+IHdpdGggYWxsIGluZm9ybWF0aW9uIHlvdVxuXHQgKiBuZWVkIHRvIGZ1bGZpbGwgdGhlIHN1cmZhY2VzLiBMaWZlY3ljbGUuXG5cdCAqIEBwYXJhbSB7IXN0cmluZz19IHBhdGggVGhlIHJlcXVlc3RlZCBwYXRoLlxuXHQgKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlfSBUaGlzIGNhbiByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZVxuXHQgKiAgICAgY29udGVudHMgb2YgdGhlIHN1cmZhY2VzIG9yIGEgcHJvbWlzZSwgd2hpY2ggd2lsbCBwYXVzZSB0aGUgbmF2aWdhdGlvblxuXHQgKiAgICAgdW50aWwgaXQgaXMgcmVzb2x2ZWQuIFRoaXMgaXMgdXNlZnVsIGZvciBsb2FkaW5nIGFzeW5jIGNvbnRlbnQuXG5cdCAqL1xuXHRsb2FkKCkge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gbG9hZCcpO1xuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1ha2VzIHRoZSBpZCBmb3IgdGhlIHNjcmVlbi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBpZCBUaGUgc2NyZWVuIGlkIHRoZSBjb250ZW50IGJlbG9uZ3MgdG9vLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRtYWtlSWRfKGlkKSB7XG5cdFx0cmV0dXJuICdzY3JlZW5fJyArIGlkO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHNjcmVlbiBpZC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBpZFxuXHQgKi9cblx0c2V0SWQoaWQpIHtcblx0XHR0aGlzLmlkID0gaWQ7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgc2NyZWVuIG1ldGEgdGFncy5cblx0ICogQHBhcmFtIHtOb2RlTGlzdHxOb2RlfSBtZXRhc1xuXHQgKi9cblx0c2V0TWV0YXMobWV0YXMpIHtcblx0XHR0aGlzLm1ldGFzID0gbWV0YXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgc2NyZWVuIHRpdGxlLlxuXHQgKiBAcGFyYW0gez9zdHJpbmc9fSB0aXRsZVxuXHQgKi9cblx0c2V0VGl0bGUodGl0bGUpIHtcblx0XHR0aGlzLnRpdGxlID0gdGl0bGU7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQ7XG5cdH1cblxufVxuXG4vKipcbiAqIEBwYXJhbSB7Kn0gb2JqZWN0XG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIGEgZ2l2ZW4gaW5zdGFuY2UgaW1wbGVtZW50c1xuICogPGNvZGU+U2NyZWVuPC9jb2RlPi5cbiAqL1xuU2NyZWVuLmlzSW1wbGVtZW50ZWRCeSA9IGZ1bmN0aW9uKG9iamVjdCkge1xuXHRyZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgU2NyZWVuO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgU2NyZWVuO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IHsgRGlzcG9zYWJsZSwgaXNEZWZBbmROb3ROdWxsIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgYXBwZW5kLCByZW1vdmVDaGlsZHJlbiwgZXhpdERvY3VtZW50IH0gZnJvbSAnbWV0YWwtZG9tJztcbmltcG9ydCBDYW5jZWxsYWJsZVByb21pc2UgZnJvbSAnbWV0YWwtcHJvbWlzZSc7XG5cbmNsYXNzIFN1cmZhY2UgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblxuXHQvKipcblx0ICogU3VyZmFjZSBjbGFzcyByZXByZXNlbnRpbmcgdGhlIHJlZmVyZW5jZXMgdG8gZWxlbWVudHMgb24gdGhlIHBhZ2UgdGhhdFxuXHQgKiBjYW4gcG90ZW50aWFsbHkgYmUgdXBkYXRlZCBieSA8Y29kZT5BcHA8L2NvZGU+LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaWRcblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihpZCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHRpZiAoIWlkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1N1cmZhY2UgZWxlbWVudCBpZCBub3Qgc3BlY2lmaWVkLiBBIHN1cmZhY2UgZWxlbWVudCByZXF1aXJlcyBhIHZhbGlkIGlkLicpO1xuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBhY3RpdmUgY2hpbGQgZWxlbWVudC5cblx0XHQgKiBAdHlwZSB7RWxlbWVudH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYWN0aXZlQ2hpbGQgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGRlZmF1bHQgY2hpbGQgZWxlbWVudC5cblx0XHQgKiBAdHlwZSB7RWxlbWVudH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZGVmYXVsdENoaWxkID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCBzdXJmYWNlIGlkLCBpZiBub3QgZm91bmQgY3JlYXRlcyBhXG5cdFx0ICogbmV3IGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIGlkLlxuXHRcdCAqIEB0eXBlIHtFbGVtZW50fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5lbGVtZW50ID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBzdXJmYWNlIGlkLlxuXHRcdCAqIEB0eXBlIHtTdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmlkID0gaWQ7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgZGVmYXVsdCB0cmFuc2l0aW9uRm4gZm9yIHRoZSBzdXJmYWNlcy5cblx0XHQgKiBAcGFyYW0gez9FbGVtZW50PX0gZnJvbSBUaGUgdmlzaWJsZSBzdXJmYWNlIGVsZW1lbnQuXG5cdFx0ICogQHBhcmFtIHs/RWxlbWVudD19IHRvIFRoZSBzdXJmYWNlIGVsZW1lbnQgdG8gYmUgZmxpcHBlZC5cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICovXG5cdFx0dGhpcy50cmFuc2l0aW9uRm4gPSBudWxsO1xuXG5cdFx0dGhpcy5kZWZhdWx0Q2hpbGQgPSB0aGlzLmdldENoaWxkKFN1cmZhY2UuREVGQVVMVCk7XG5cdFx0dGhpcy5tYXliZVdyYXBDb250ZW50QXNEZWZhdWx0XygpO1xuXHRcdHRoaXMuYWN0aXZlQ2hpbGQgPSB0aGlzLmRlZmF1bHRDaGlsZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHNjcmVlbiBjb250ZW50IHRvIGEgc3VyZmFjZS4gSWYgY29udGVudCBoYXNuJ3QgYmVlbiBwYXNzZWQsIHNlZSBpZlxuXHQgKiBhbiBlbGVtZW50IGV4aXN0cyBpbiB0aGUgRE9NIHRoYXQgbWF0Y2hlcyB0aGUgaWQuIEJ5IGNvbnZlbnRpb24sIHRoZVxuXHQgKiBlbGVtZW50IHNob3VsZCBhbHJlYWR5IGJlIG5lc3RlZCBpbiB0aGUgcmlnaHQgZWxlbWVudCBhbmQgc2hvdWxkIGhhdmUgYW5cblx0ICogaWQgdGhhdCBpcyBhIGNvbmNhdGVudGF0aW9uIG9mIHRoZSBzdXJmYWNlIGlkICsgJy0nICsgdGhlIHNjcmVlbiBpZC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkIHRoZSBjb250ZW50IGJlbG9uZ3MgdG9vLlxuXHQgKiBAcGFyYW0gez9zdHJpbmd8RWxlbWVudD19IG9wdF9jb250ZW50IFRoZSBzdHJpbmcgY29udGVudCBvciBlbGVtZW50IHRvXG5cdCAqICAgICBhZGQgYmUgYWRkZWQgYXMgc3VyZmFjZSBjb250ZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fVxuXHQgKi9cblx0YWRkQ29udGVudChzY3JlZW5JZCwgb3B0X2NvbnRlbnQpIHtcblx0XHR2YXIgY2hpbGQgPSB0aGlzLmRlZmF1bHRDaGlsZDtcblxuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwob3B0X2NvbnRlbnQpKSB7XG5cdFx0XHRjaGlsZCA9IHRoaXMuZ2V0Q2hpbGQoc2NyZWVuSWQpO1xuXHRcdFx0aWYgKGNoaWxkKSB7XG5cdFx0XHRcdHJlbW92ZUNoaWxkcmVuKGNoaWxkKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNoaWxkID0gdGhpcy5jcmVhdGVDaGlsZChzY3JlZW5JZCk7XG5cdFx0XHRcdHRoaXMudHJhbnNpdGlvbihjaGlsZCwgbnVsbCk7XG5cdFx0XHR9XG5cdFx0XHRhcHBlbmQoY2hpbGQsIG9wdF9jb250ZW50KTtcblx0XHR9XG5cblx0XHR2YXIgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudCgpO1xuXG5cdFx0aWYgKGVsZW1lbnQgJiYgY2hpbGQpIHtcblx0XHRcdGFwcGVuZChlbGVtZW50LCBjaGlsZCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNoaWxkO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgY2hpbGQgbm9kZSBmb3IgdGhlIHN1cmZhY2UuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2NyZWVuSWQgVGhlIHNjcmVlbiBpZC5cblx0ICogQHJldHVybiB7RWxlbWVudH1cblx0ICovXG5cdGNyZWF0ZUNoaWxkKHNjcmVlbklkKSB7XG5cdFx0dmFyIGNoaWxkID0gZ2xvYmFscy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHRjaGlsZC5zZXRBdHRyaWJ1dGUoJ2lkJywgdGhpcy5tYWtlSWRfKHNjcmVlbklkKSk7XG5cdFx0cmV0dXJuIGNoaWxkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgY2hpbGQgbm9kZSBvZiB0aGUgc3VyZmFjZS5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkLlxuXHQgKiBAcmV0dXJuIHs/RWxlbWVudH1cblx0ICovXG5cdGdldENoaWxkKHNjcmVlbklkKSB7XG5cdFx0cmV0dXJuIGdsb2JhbHMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5tYWtlSWRfKHNjcmVlbklkKSk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc3VyZmFjZSBlbGVtZW50IGZyb20gZWxlbWVudCwgYW5kIHNldHMgaXQgdG8gdGhlIGVsIHByb3BlcnR5IG9mXG5cdCAqIHRoZSBjdXJyZW50IGluc3RhbmNlLlxuXHQgKiA8Y29kZT50aGlzLmVsZW1lbnQ8L2NvZGU+IHdpbGwgYmUgdXNlZC5cblx0ICogQHJldHVybiB7P0VsZW1lbnR9IFRoZSBjdXJyZW50IHN1cmZhY2UgZWxlbWVudC5cblx0ICovXG5cdGdldEVsZW1lbnQoKSB7XG5cdFx0aWYgKHRoaXMuZWxlbWVudCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWxlbWVudDtcblx0XHR9XG5cdFx0dGhpcy5lbGVtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmlkKTtcblx0XHRyZXR1cm4gdGhpcy5lbGVtZW50O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHN1cmZhY2UgaWQuXG5cdCAqIEByZXR1cm4ge1N0cmluZ31cblx0ICovXG5cdGdldElkKCkge1xuXHRcdHJldHVybiB0aGlzLmlkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHN1cmZhY2UgdHJhbnNpdGlvbiBmdW5jdGlvbi5cblx0ICogU2VlIDxjb2RlPlN1cmZhY2UuZGVmYXVsdFRyYW5zaXRpb248L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHs/RnVuY3Rpb249fSBUaGUgdHJhbnNpdGlvbiBmdW5jdGlvbi5cblx0ICovXG5cdGdldFRyYW5zaXRpb25GbigpIHtcblx0XHRyZXR1cm4gdGhpcy50cmFuc2l0aW9uRm47XG5cdH1cblxuXHQvKipcblx0ICogTWFrZXMgdGhlIGlkIGZvciB0aGUgZWxlbWVudCB0aGF0IGhvbGRzIGNvbnRlbnQgZm9yIGEgc2NyZWVuLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQgdGhlIGNvbnRlbnQgYmVsb25ncyB0b28uXG5cdCAqIEByZXR1cm4ge1N0cmluZ31cblx0ICogQHByaXZhdGVcblx0ICovXG5cdG1ha2VJZF8oc2NyZWVuSWQpIHtcblx0XHRyZXR1cm4gdGhpcy5pZCArICctJyArIHNjcmVlbklkO1xuXHR9XG5cblx0LyoqXG5cdCAqIElmIGRlZmF1bHQgY2hpbGQgaXMgbWlzc2luZywgd3JhcHMgc3VyZmFjZSBjb250ZW50IGFzIGRlZmF1bHQgY2hpbGQuIElmXG5cdCAqIHN1cmZhY2UgaGF2ZSBzdGF0aWMgY29udGVudCwgbWFrZSBzdXJlIHRvIHBsYWNlIGFcblx0ICogPGNvZGU+c3VyZmFjZUlkLWRlZmF1bHQ8L2NvZGU+IGVsZW1lbnQgaW5zaWRlIHN1cmZhY2UsIG9ubHkgY29udGVudHNcblx0ICogaW5zaWRlIHRoZSBkZWZhdWx0IGNoaWxkIHdpbGwgYmUgcmVwbGFjZWQgYnkgbmF2aWdhdGlvbi5cblx0ICovXG5cdG1heWJlV3JhcENvbnRlbnRBc0RlZmF1bHRfKCkge1xuXHRcdHZhciBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KCk7XG5cdFx0aWYgKGVsZW1lbnQgJiYgIXRoaXMuZGVmYXVsdENoaWxkKSB7XG5cdFx0XHR2YXIgZnJhZ21lbnQgPSBnbG9iYWxzLmRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblx0XHRcdHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpIHtcblx0XHRcdFx0ZnJhZ21lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudC5maXJzdENoaWxkKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuZGVmYXVsdENoaWxkID0gdGhpcy5hZGRDb250ZW50KFN1cmZhY2UuREVGQVVMVCwgZnJhZ21lbnQpO1xuXHRcdFx0dGhpcy50cmFuc2l0aW9uKG51bGwsIHRoaXMuZGVmYXVsdENoaWxkKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgc3VyZmFjZSBpZC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBpZFxuXHQgKi9cblx0c2V0SWQoaWQpIHtcblx0XHR0aGlzLmlkID0gaWQ7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgc3VyZmFjZSB0cmFuc2l0aW9uIGZ1bmN0aW9uLlxuXHQgKiBTZWUgPGNvZGU+U3VyZmFjZS5kZWZhdWx0VHJhbnNpdGlvbjwvY29kZT4uXG5cdCAqIEBwYXJhbSB7P0Z1bmN0aW9uPX0gdHJhbnNpdGlvbkZuIFRoZSB0cmFuc2l0aW9uIGZ1bmN0aW9uLlxuXHQgKi9cblx0c2V0VHJhbnNpdGlvbkZuKHRyYW5zaXRpb25Gbikge1xuXHRcdHRoaXMudHJhbnNpdGlvbkZuID0gdHJhbnNpdGlvbkZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNob3dzIHNjcmVlbiBjb250ZW50IGZyb20gYSBzdXJmYWNlLlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc2NyZWVuSWQgVGhlIHNjcmVlbiBpZCB0byBzaG93LlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IFBhdXNlcyB0aGUgbmF2aWdhdGlvbiB1bnRpbCBpdCBpcyByZXNvbHZlZC5cblx0ICovXG5cdHNob3coc2NyZWVuSWQpIHtcblx0XHR2YXIgZnJvbSA9IHRoaXMuYWN0aXZlQ2hpbGQ7XG5cdFx0dmFyIHRvID0gdGhpcy5nZXRDaGlsZChzY3JlZW5JZCk7XG5cdFx0aWYgKCF0bykge1xuXHRcdFx0dG8gPSB0aGlzLmRlZmF1bHRDaGlsZDtcblx0XHR9XG5cdFx0dGhpcy5hY3RpdmVDaGlsZCA9IHRvO1xuXHRcdHJldHVybiB0aGlzLnRyYW5zaXRpb24oZnJvbSwgdG8pLnRoZW5BbHdheXMoKCkgPT4ge1xuXHRcdFx0aWYgKGZyb20gJiYgZnJvbSAhPT0gdG8pIHtcblx0XHRcdFx0ZXhpdERvY3VtZW50KGZyb20pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgc2NyZWVuIGNvbnRlbnQgZnJvbSBhIHN1cmZhY2UuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2NyZWVuSWQgVGhlIHNjcmVlbiBpZCB0byByZW1vdmUuXG5cdCAqL1xuXHRyZW1vdmUoc2NyZWVuSWQpIHtcblx0XHR2YXIgY2hpbGQgPSB0aGlzLmdldENoaWxkKHNjcmVlbklkKTtcblx0XHRpZiAoY2hpbGQpIHtcblx0XHRcdGV4aXREb2N1bWVudChjaGlsZCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge1N0cmluZ31cblx0ICovXG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiB0aGlzLmlkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEludm9rZXMgdGhlIHRyYW5zaXRpb24gZnVuY3Rpb24gc3BlY2lmaWVkIG9uIDxjb2RlPnRyYW5zaXRpb248L2NvZGU+IGF0dHJpYnV0ZS5cblx0ICogQHBhcmFtIHs/RWxlbWVudD19IGZyb21cblx0ICogQHBhcmFtIHs/RWxlbWVudD19IHRvXG5cdCAqIEByZXR1cm4gez9DYW5jZWxsYWJsZVByb21pc2U9fSBUaGlzIGNhbiByZXR1cm4gYSBwcm9taXNlLCB3aGljaCB3aWxsIHBhdXNlIHRoZVxuXHQgKiAgICAgbmF2aWdhdGlvbiB1bnRpbCBpdCBpcyByZXNvbHZlZC5cblx0ICovXG5cdHRyYW5zaXRpb24oZnJvbSwgdG8pIHtcblx0XHR2YXIgdHJhbnNpdGlvbkZuID0gdGhpcy50cmFuc2l0aW9uRm4gfHwgU3VyZmFjZS5kZWZhdWx0VHJhbnNpdGlvbjtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUodHJhbnNpdGlvbkZuLmNhbGwodGhpcywgZnJvbSwgdG8pKTtcblx0fVxuXG59XG5cbi8qKlxuICAgKiBIb2xkcyB0aGUgZGVmYXVsdCBzdXJmYWNlIG5hbWUuIEVsZW1lbnRzIG9uIHRoZSBwYWdlIG11c3QgY29udGFpbiBhIGNoaWxkXG4gICAqIGVsZW1lbnQgY29udGFpbmluZyB0aGUgZGVmYXVsdCBjb250ZW50LCB0aGlzIGVsZW1lbnQgbXVzdCBiZSBhcyBmb2xsb3dpbmc6XG4gICAqXG4gICAqIEV4YW1wbGU6XG4gICAqIDxjb2RlPlxuICAgKiAgIDxkaXYgaWQ9XCJteXN1cmZhY2VcIj5cbiAgICogICAgIDxkaXYgaWQ9XCJteXN1cmZhY2UtZGVmYXVsdFwiPkRlZmF1bHQgc3VyZmFjZSBjb250ZW50LjwvZGl2PlxuICAgKiAgIDwvZGl2PlxuICAgKiA8L2NvZGU+XG4gICAqXG4gICAqIFRoZSBkZWZhdWx0IGNvbnRlbnQgaXMgcmVsZXZhbnQgZm9yIHRoZSBpbml0aWFsIHBhZ2UgY29udGVudC4gV2hlbiBhXG4gICAqIHNjcmVlbiBkb2Vzbid0IHByb3ZpZGUgY29udGVudCBmb3IgdGhlIHN1cmZhY2UgdGhlIGRlZmF1bHQgY29udGVudCBpc1xuICAgKiByZXN0b3JlZCBpbnRvIHRoZSBwYWdlLlxuICAgKlxuICAgKiBAdHlwZSB7IVN0cmluZ31cbiAgICogQGRlZmF1bHQgZGVmYXVsdFxuICAgKiBAc3RhdGljXG4gICAqL1xuU3VyZmFjZS5ERUZBVUxUID0gJ2RlZmF1bHQnO1xuXG4vKipcbiAqIEhvbGRzIHRoZSBkZWZhdWx0IHRyYW5zaXRpb24gZm9yIGFsbCBzdXJmYWNlcy4gRWFjaCBzdXJmYWNlIGNvdWxkIGhhdmUgaXRzXG4gKiBvd24gdHJhbnNpdGlvbi5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIDxjb2RlPlxuICogc3VyZmFjZS5zZXRUcmFuc2l0aW9uRm4oZnVuY3Rpb24oZnJvbSwgdG8pIHtcbiAqICAgaWYgKGZyb20pIHtcbiAqICAgICBmcm9tLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gKiAgICAgZnJvbS5jbGFzc0xpc3QucmVtb3ZlKCdmbGlwcGVkJyk7XG4gKiAgIH1cbiAqICAgaWYgKHRvKSB7XG4gKiAgICAgdG8uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gKiAgICAgdG8uY2xhc3NMaXN0LmFkZCgnZmxpcHBlZCcpO1xuICogICB9XG4gKiAgIHJldHVybiBudWxsO1xuICogfSk7XG4gKiA8L2NvZGU+XG4gKlxuICogQHBhcmFtIHs/RWxlbWVudD19IGZyb20gVGhlIHZpc2libGUgc3VyZmFjZSBlbGVtZW50LlxuICogQHBhcmFtIHs/RWxlbWVudD19IHRvIFRoZSBzdXJmYWNlIGVsZW1lbnQgdG8gYmUgZmxpcHBlZC5cbiAqIEBzdGF0aWNcbiAqL1xuU3VyZmFjZS5kZWZhdWx0VHJhbnNpdGlvbiA9IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG5cdGlmIChmcm9tKSB7XG5cdFx0ZnJvbS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdGZyb20uY2xhc3NMaXN0LnJlbW92ZSgnZmxpcHBlZCcpO1xuXHR9XG5cdGlmICh0bykge1xuXHRcdHRvLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXHRcdHRvLmNsYXNzTGlzdC5hZGQoJ2ZsaXBwZWQnKTtcblx0fVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU3VyZmFjZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgYWRkQ2xhc3NlcywgZGVsZWdhdGUsIG1hdGNoLCBvbiwgcmVtb3ZlQ2xhc3NlcyB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgeyBhcnJheSwgYXN5bmMsIGlzRGVmQW5kTm90TnVsbCwgaXNTdHJpbmcsIG9iamVjdCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgRXZlbnRIYW5kbGVyIH0gZnJvbSAnbWV0YWwtZXZlbnRzJztcbmltcG9ydCBDYW5jZWxsYWJsZVByb21pc2UgZnJvbSAnbWV0YWwtcHJvbWlzZSc7XG5pbXBvcnQgZGVib3VuY2UgZnJvbSAnbWV0YWwtZGVib3VuY2UnO1xuaW1wb3J0IGdsb2JhbHMgZnJvbSAnLi4vZ2xvYmFscy9nbG9iYWxzJztcbmltcG9ydCBSb3V0ZSBmcm9tICcuLi9yb3V0ZS9Sb3V0ZSc7XG5pbXBvcnQgU2NyZWVuIGZyb20gJy4uL3NjcmVlbi9TY3JlZW4nO1xuaW1wb3J0IFN1cmZhY2UgZnJvbSAnLi4vc3VyZmFjZS9TdXJmYWNlJztcbmltcG9ydCBVcmkgZnJvbSAnbWV0YWwtdXJpJztcbmltcG9ydCB1dGlscyBmcm9tICcuLi91dGlscy91dGlscyc7XG5cbmNvbnN0IE5hdmlnYXRpb25TdHJhdGVneSA9IHtcblx0SU1NRURJQVRFOiAnaW1tZWRpYXRlJyxcblx0U0NIRURVTEVfTEFTVDogJ3NjaGVkdWxlTGFzdCdcbn07XG5cbmNsYXNzIEFwcCBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG5cblx0LyoqXG5cdCAqIEFwcCBjbGFzcyB0aGF0IGhhbmRsZSByb3V0ZXMgYW5kIHNjcmVlbnMgbGlmZWN5Y2xlLlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQGV4dGVuZHMge0V2ZW50RW1pdHRlcn1cblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgYWN0aXZlIHNjcmVlbi5cblx0XHQgKiBAdHlwZSB7P1NjcmVlbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5hY3RpdmVTY3JlZW4gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGFjdGl2ZSBwYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5IHBhcmFtZXRlcnMuXG5cdFx0ICogQHR5cGUgez9zdHJpbmd9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYWN0aXZlUGF0aCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBBbGxvd3MgcHJldmVudCBuYXZpZ2F0ZSBmcm9tIGRvbSBwcmV2ZW50ZWQgZXZlbnQuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgdHJ1ZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmFsbG93UHJldmVudE5hdmlnYXRlID0gdHJ1ZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGxpbmsgYmFzZSBwYXRoLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0ICcnXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYmFzZVBhdGggPSAnJztcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSB2YWx1ZSBvZiB0aGUgYnJvd3NlciBwYXRoIGJlZm9yZSBhIG5hdmlnYXRpb24gaXMgcGVyZm9ybWVkLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IHRoZSBjdXJyZW50IGJyb3dzZXIgcGF0aC5cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5icm93c2VyUGF0aEJlZm9yZU5hdmlnYXRlID0gdXRpbHMuZ2V0Q3VycmVudEJyb3dzZXJQYXRoV2l0aG91dEhhc2goKTtcblxuXHRcdC8qKlxuXHRcdCAqIENhcHR1cmVzIHNjcm9sbCBwb3NpdGlvbiBmcm9tIHNjcm9sbCBldmVudC5cblx0XHQgKiBAdHlwZSB7IWJvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgdHJ1ZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmNhcHR1cmVTY3JvbGxQb3NpdGlvbkZyb21TY3JvbGxFdmVudCA9IHRydWU7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgZGVmYXVsdCBwYWdlIHRpdGxlLlxuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmRlZmF1bHRUaXRsZSA9IGdsb2JhbHMuZG9jdW1lbnQudGl0bGU7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgZm9ybSBzZWxlY3RvciB0byBkZWZpbmUgZm9ybXMgdGhhdCBhcmUgcm91dGVkLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IGZvcm1bZW5jdHlwZT1cIm11bHRpcGFydC9mb3JtLWRhdGFcIl06bm90KFtkYXRhLXNlbm5hLW9mZl0pXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZm9ybVNlbGVjdG9yID0gJ2Zvcm1bZW5jdHlwZT1cIm11bHRpcGFydC9mb3JtLWRhdGFcIl06bm90KFtkYXRhLXNlbm5hLW9mZl0pJztcblxuXHRcdC8qKlxuXHRcdCAqIFdoZW4gZW5hYmxlZCwgdGhlIHJvdXRlIG1hdGNoaW5nIGlnbm9yZXMgcXVlcnkgc3RyaW5nIGZyb20gdGhlIHBhdGguXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgZmFsc2Vcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5pZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGggPSBmYWxzZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBsaW5rIHNlbGVjdG9yIHRvIGRlZmluZSBsaW5rcyB0aGF0IGFyZSByb3V0ZWQuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgYTpub3QoW2RhdGEtc2VubmEtb2ZmXSlcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5saW5rU2VsZWN0b3IgPSAnYTpub3QoW2RhdGEtc2VubmEtb2ZmXSk6bm90KFt0YXJnZXQ9XCJfYmxhbmtcIl0pJztcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBsb2FkaW5nIGNzcyBjbGFzcy5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBzZW5uYS1sb2FkaW5nXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubG9hZGluZ0Nzc0NsYXNzID0gJ3Nlbm5hLWxvYWRpbmcnO1xuXG5cdFx0LyoqXG5cdFx0ICogVXNpbmcgdGhlIEhpc3RvcnkgQVBJIHRvIG1hbmFnZSB5b3VyIFVSTHMgaXMgYXdlc29tZSBhbmQsIGFzIGl0IGhhcHBlbnMsXG5cdFx0ICogYSBjcnVjaWFsIGZlYXR1cmUgb2YgZ29vZCB3ZWIgYXBwcy4gT25lIG9mIGl0cyBkb3duc2lkZXMsIGhvd2V2ZXIsIGlzXG5cdFx0ICogdGhhdCBzY3JvbGwgcG9zaXRpb25zIGFyZSBzdG9yZWQgYW5kIHRoZW4sIG1vcmUgaW1wb3J0YW50bHksIHJlc3RvcmVkXG5cdFx0ICogd2hlbmV2ZXIgeW91IHRyYXZlcnNlIHRoZSBoaXN0b3J5LiBUaGlzIG9mdGVuIG1lYW5zIHVuc2lnaHRseSBqdW1wcyBhc1xuXHRcdCAqIHRoZSBzY3JvbGwgcG9zaXRpb24gY2hhbmdlcyBhdXRvbWF0aWNhbGx5LCBhbmQgZXNwZWNpYWxseSBzbyBpZiB5b3VyIGFwcFxuXHRcdCAqIGRvZXMgdHJhbnNpdGlvbnMsIG9yIGNoYW5nZXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBwYWdlIGluIGFueSB3YXkuXG5cdFx0ICogVWx0aW1hdGVseSB0aGlzIGxlYWRzIHRvIGFuIGhvcnJpYmxlIHVzZXIgZXhwZXJpZW5jZS4gVGhlIGdvb2QgbmV3cyBpcyxcblx0XHQgKiBob3dldmVyLCB0aGF0IHRoZXJl4oCZcyBhIHBvdGVudGlhbCBmaXg6IGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24uXG5cdFx0ICogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vd2ViL3VwZGF0ZXMvMjAxNS8wOS9oaXN0b3J5LWFwaS1zY3JvbGwtcmVzdG9yYXRpb25cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvblN1cHBvcnRlZCA9ICgnc2Nyb2xsUmVzdG9yYXRpb24nIGluIGdsb2JhbHMud2luZG93Lmhpc3RvcnkpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBzZXQgdG8gTmF2aWdhdGlvblN0cmF0ZWd5LlNDSEVEVUxFX0xBU1QgbWVhbnMgdGhhdCB0aGUgY3VycmVudCBuYXZpZ2F0aW9uXG5cdFx0ICogY2Fubm90IGJlIENhbmNlbGxlZCB0byBzdGFydCBhbm90aGVyIGFuZCB3aWxsIGJlIHF1ZXVlZCBpblxuXHRcdCAqIHNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZS4gV2hlbiBOYXZpZ2F0aW9uU3RyYXRlZ3kuSU1NRURJQVRFIG1lYW5zIHRoYXQgYWxsXG5cdFx0ICogbmF2aWdhdGlvbiB3aWxsIGJlIGNhbmNlbGxlZCB0byBzdGFydCBhbm90aGVyLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IGltbWVkaWF0ZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9IE5hdmlnYXRpb25TdHJhdGVneS5JTU1FRElBVEU7XG5cblx0XHQvKipcblx0XHQgKiBXaGVuIHNldCB0byB0cnVlIHRoZXJlIGlzIGEgcGVuZGluZ05hdmlnYXRlIHRoYXQgaGFzIG5vdCB5ZXQgYmVlblxuXHRcdCAqIHJlc29sdmVkIG9yIHJlamVjdGVkLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IGZhbHNlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyA9IGZhbHNlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgYSBkZWZlcnJlZCB3aXRoIHRoZSBjdXJyZW50IG5hdmlnYXRpb24uXG5cdFx0ICogQHR5cGUgez9DYW5jZWxsYWJsZVByb21pc2V9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgd2luZG93IGhvcml6b250YWwgc2Nyb2xsIHBvc2l0aW9uIHdoZW4gdGhlIG5hdmlnYXRpb24gdXNpbmdcblx0XHQgKiBiYWNrIG9yIGZvcndhcmQgaGFwcGVucyB0byBiZSByZXN0b3JlZCBhZnRlciB0aGUgc3VyZmFjZXMgYXJlIHVwZGF0ZWQuXG5cdFx0ICogQHR5cGUgeyFOdW1iZXJ9XG5cdFx0ICogQGRlZmF1bHQgMFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBvcHN0YXRlU2Nyb2xsTGVmdCA9IDA7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgd2luZG93IHZlcnRpY2FsIHNjcm9sbCBwb3NpdGlvbiB3aGVuIHRoZSBuYXZpZ2F0aW9uIHVzaW5nXG5cdFx0ICogYmFjayBvciBmb3J3YXJkIGhhcHBlbnMgdG8gYmUgcmVzdG9yZWQgYWZ0ZXIgdGhlIHN1cmZhY2VzIGFyZSB1cGRhdGVkLlxuXHRcdCAqIEB0eXBlIHshTnVtYmVyfVxuXHRcdCAqIEBkZWZhdWx0IDBcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5wb3BzdGF0ZVNjcm9sbFRvcCA9IDA7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgcmVkaXJlY3QgcGF0aCBjb250YWluaW5nIHRoZSBxdWVyeSBwYXJhbWV0ZXJzLlxuXHRcdCAqIEB0eXBlIHs/c3RyaW5nfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnJlZGlyZWN0UGF0aCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgc2NyZWVuIHJvdXRlcyBjb25maWd1cmF0aW9uLlxuXHRcdCAqIEB0eXBlIHs/QXJyYXl9XG5cdFx0ICogQGRlZmF1bHQgW11cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5yb3V0ZXMgPSBbXTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGEgcXVldWUgdGhhdCBzdG9yZXMgZXZlcnkgRE9NIGV2ZW50IHRoYXQgY2FuIGluaXRpYXRlIGEgbmF2aWdhdGlvbi5cblx0XHQgKiBAdHlwZSB7IUV2ZW50fVxuXHRcdCAqIEBkZWZhdWx0IFtdXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlID0gW107XG5cblx0XHQvKipcblx0XHQgKiBNYXBzIHRoZSBzY3JlZW4gaW5zdGFuY2VzIGJ5IHRoZSB1cmwgY29udGFpbmluZyB0aGUgcGFyYW1ldGVycy5cblx0XHQgKiBAdHlwZSB7P09iamVjdH1cblx0XHQgKiBAZGVmYXVsdCB7fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnNjcmVlbnMgPSB7fTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZW4gc2V0IHRvIHRydWUgdGhlIGZpcnN0IGVycm9uZW91cyBwb3BzdGF0ZSBmaXJlZCBvbiBwYWdlIGxvYWQgd2lsbCBiZVxuXHRcdCAqIGlnbm9yZWQsIG9ubHkgaWYgPGNvZGU+Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5zdGF0ZTwvY29kZT4gaXMgYWxzb1xuXHRcdCAqIDxjb2RlPm51bGw8L2NvZGU+LlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IGZhbHNlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuc2tpcExvYWRQb3BzdGF0ZSA9IGZhbHNlO1xuXG5cdFx0LyoqXG5cdFx0ICogTWFwcyB0aGF0IGluZGV4IHRoZSBzdXJmYWNlcyBpbnN0YW5jZXMgYnkgdGhlIHN1cmZhY2UgaWQuXG5cdFx0ICogQHR5cGUgez9PYmplY3R9XG5cdFx0ICogQGRlZmF1bHQge31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zdXJmYWNlcyA9IHt9O1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBzZXQgdG8gdHJ1ZSwgbW92ZXMgdGhlIHNjcm9sbCBwb3NpdGlvbiBhZnRlciBwb3BzdGF0ZSwgb3IgdG8gdGhlXG5cdFx0ICogdG9wIG9mIHRoZSB2aWV3cG9ydCBmb3IgbmV3IG5hdmlnYXRpb24uIElmIGZhbHNlLCB0aGUgYnJvd3NlciB3aWxsXG5cdFx0ICogdGFrZSBjYXJlIG9mIHNjcm9sbCByZXN0b3JhdGlvbi5cblx0XHQgKiBAdHlwZSB7IWJvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgdHJ1ZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnVwZGF0ZVNjcm9sbFBvc2l0aW9uID0gdHJ1ZTtcblxuXHRcdHRoaXMuYXBwRXZlbnRIYW5kbGVyc18gPSBuZXcgRXZlbnRIYW5kbGVyKCk7XG5cblx0XHR0aGlzLmFwcEV2ZW50SGFuZGxlcnNfLmFkZChcblx0XHRcdG9uKGdsb2JhbHMud2luZG93LCAnc2Nyb2xsJywgZGVib3VuY2UodGhpcy5vblNjcm9sbF8uYmluZCh0aGlzKSwgMTAwKSksXG5cdFx0XHRvbihnbG9iYWxzLndpbmRvdywgJ2xvYWQnLCB0aGlzLm9uTG9hZF8uYmluZCh0aGlzKSksXG5cdFx0XHRvbihnbG9iYWxzLndpbmRvdywgJ3BvcHN0YXRlJywgdGhpcy5vblBvcHN0YXRlXy5iaW5kKHRoaXMpKVxuXHRcdCk7XG5cblx0XHR0aGlzLm9uKCdzdGFydE5hdmlnYXRlJywgdGhpcy5vblN0YXJ0TmF2aWdhdGVfKTtcblx0XHR0aGlzLm9uKCdiZWZvcmVOYXZpZ2F0ZScsIHRoaXMub25CZWZvcmVOYXZpZ2F0ZV8pO1xuXHRcdHRoaXMub24oJ2JlZm9yZU5hdmlnYXRlJywgdGhpcy5vbkJlZm9yZU5hdmlnYXRlRGVmYXVsdF8sIHRydWUpO1xuXHRcdHRoaXMub24oJ2JlZm9yZVVubG9hZCcsIHRoaXMub25CZWZvcmVVbmxvYWREZWZhdWx0Xyk7XG5cblx0XHR0aGlzLnNldExpbmtTZWxlY3Rvcih0aGlzLmxpbmtTZWxlY3Rvcik7XG5cdFx0dGhpcy5zZXRGb3JtU2VsZWN0b3IodGhpcy5mb3JtU2VsZWN0b3IpO1xuXG5cdFx0dGhpcy5tYXliZU92ZXJsb2FkQmVmb3JlVW5sb2FkXygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgb25lIG9yIG1vcmUgc2NyZWVucyB0byB0aGUgYXBwbGljYXRpb24uXG5cdCAqXG5cdCAqIEV4YW1wbGU6XG5cdCAqXG5cdCAqIDxjb2RlPlxuXHQgKiAgIGFwcC5hZGRSb3V0ZXMoeyBwYXRoOiAnL2ZvbycsIGhhbmRsZXI6IEZvb1NjcmVlbiB9KTtcblx0ICogICBvclxuXHQgKiAgIGFwcC5hZGRSb3V0ZXMoW3sgcGF0aDogJy9mb28nLCBoYW5kbGVyOiBmdW5jdGlvbihyb3V0ZSkgeyByZXR1cm4gbmV3IEZvb1NjcmVlbigpOyB9IH1dKTtcblx0ICogPC9jb2RlPlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3Ige0FycmF5fSByb3V0ZXMgU2luZ2xlIG9iamVjdCBvciBhbiBhcnJheSBvZiBvYmplY3QuXG5cdCAqICAgICBFYWNoIG9iamVjdCBzaG91bGQgY29udGFpbiA8Y29kZT5wYXRoPC9jb2RlPiBhbmQgPGNvZGU+c2NyZWVuPC9jb2RlPi5cblx0ICogICAgIFRoZSA8Y29kZT5wYXRoPC9jb2RlPiBzaG91bGQgYmUgYSBzdHJpbmcgb3IgYSByZWdleCB0aGF0IG1hcHMgdGhlXG5cdCAqICAgICBuYXZpZ2F0aW9uIHJvdXRlIHRvIGEgc2NyZWVuIGNsYXNzIGRlZmluaXRpb24gKG5vdCBhbiBpbnN0YW5jZSksIGUuZzpcblx0ICogICAgICAgICA8Y29kZT57IHBhdGg6IFwiL2hvbWU6cGFyYW0xXCIsIGhhbmRsZXI6IE15U2NyZWVuIH08L2NvZGU+XG5cdCAqICAgICAgICAgPGNvZGU+eyBwYXRoOiAvZm9vLisvLCBoYW5kbGVyOiBNeVNjcmVlbiB9PC9jb2RlPlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRhZGRSb3V0ZXMocm91dGVzKSB7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KHJvdXRlcykpIHtcblx0XHRcdHJvdXRlcyA9IFtyb3V0ZXNdO1xuXHRcdH1cblx0XHRyb3V0ZXMuZm9yRWFjaCgocm91dGUpID0+IHtcblx0XHRcdGlmICghKHJvdXRlIGluc3RhbmNlb2YgUm91dGUpKSB7XG5cdFx0XHRcdHJvdXRlID0gbmV3IFJvdXRlKHJvdXRlLnBhdGgsIHJvdXRlLmhhbmRsZXIpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5yb3V0ZXMucHVzaChyb3V0ZSk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBvbmUgb3IgbW9yZSBzdXJmYWNlcyB0byB0aGUgYXBwbGljYXRpb24uXG5cdCAqIEBwYXJhbSB7U3VyZmFjZXxTdHJpbmd8QXJyYXkuPFN1cmZhY2V8U3RyaW5nPn0gc3VyZmFjZXNcblx0ICogICAgIFN1cmZhY2UgZWxlbWVudCBpZCBvciBzdXJmYWNlIGluc3RhbmNlLiBZb3UgY2FuIGFsc28gcGFzcyBhbiBBcnJheVxuXHQgKiAgICAgd2hpY2hjb250YWlucyBzdXJmYWNlIGluc3RhbmNlcyBvciBpZC4gSW4gY2FzZSBvZiBJRCwgdGhlc2Ugc2hvdWxkIGJlXG5cdCAqICAgICB0aGUgaWQgb2Ygc3VyZmFjZSBlbGVtZW50LlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRhZGRTdXJmYWNlcyhzdXJmYWNlcykge1xuXHRcdGlmICghQXJyYXkuaXNBcnJheShzdXJmYWNlcykpIHtcblx0XHRcdHN1cmZhY2VzID0gW3N1cmZhY2VzXTtcblx0XHR9XG5cdFx0c3VyZmFjZXMuZm9yRWFjaCgoc3VyZmFjZSkgPT4ge1xuXHRcdFx0aWYgKGlzU3RyaW5nKHN1cmZhY2UpKSB7XG5cdFx0XHRcdHN1cmZhY2UgPSBuZXcgU3VyZmFjZShzdXJmYWNlKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuc3VyZmFjZXNbc3VyZmFjZS5nZXRJZCgpXSA9IHN1cmZhY2U7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBpZiBjYW4gbmF2aWdhdGUgdG8gcGF0aC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSB1cmxcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGNhbk5hdmlnYXRlKHVybCkge1xuXHRcdGNvbnN0IHVyaSA9IHV0aWxzLmlzV2ViVXJpKHVybCk7XG5cblx0XHRpZiAoIXVyaSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGNvbnN0IHBhdGggPSB1dGlscy5nZXRVcmxQYXRoKHVybCk7XG5cblx0XHRpZiAoIXRoaXMuaXNMaW5rU2FtZU9yaWdpbl8odXJpLmdldEhvc3QoKSkpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdPZmZzaXRlIGxpbmsgY2xpY2tlZCcpO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAoIXRoaXMuaXNTYW1lQmFzZVBhdGhfKHBhdGgpKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnTGluayBjbGlja2VkIG91dHNpZGUgYXBwXFwncyBiYXNlIHBhdGgnKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0Ly8gUHJldmVudHMgbmF2aWdhdGlvbiBpZiBpdCdzIGEgaGFzaCBjaGFuZ2Ugb24gdGhlIHNhbWUgdXJsLlxuXHRcdGlmICh1cmkuZ2V0SGFzaCgpICYmIHV0aWxzLmlzQ3VycmVudEJyb3dzZXJQYXRoKHBhdGgpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5maW5kUm91dGUocGF0aCkpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdObyByb3V0ZSBmb3IgJyArIHBhdGgpO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFyIHNjcmVlbnMgY2FjaGUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGNsZWFyU2NyZWVuc0NhY2hlKCkge1xuXHRcdE9iamVjdC5rZXlzKHRoaXMuc2NyZWVucykuZm9yRWFjaCgocGF0aCkgPT4ge1xuXHRcdFx0aWYgKHBhdGggPT09IHRoaXMuYWN0aXZlUGF0aCkge1xuXHRcdFx0XHR0aGlzLmFjdGl2ZVNjcmVlbi5jbGVhckNhY2hlKCk7XG5cdFx0XHR9IGVsc2UgaWYgKCEodGhpcy5pc05hdmlnYXRpb25QZW5kaW5nICYmIHRoaXMucGVuZGluZ05hdmlnYXRlLnBhdGggPT09IHBhdGgpKSB7XG5cdFx0XHRcdHRoaXMucmVtb3ZlU2NyZWVuKHBhdGgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlcyBvciBjcmVhdGUgYSBzY3JlZW4gaW5zdGFuY2UgdG8gYSBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcmV0dXJuIHtTY3JlZW59XG5cdCAqL1xuXHRjcmVhdGVTY3JlZW5JbnN0YW5jZShwYXRoLCByb3V0ZSkge1xuXHRcdGlmICghdGhpcy5wZW5kaW5nTmF2aWdhdGUgJiYgcGF0aCA9PT0gdGhpcy5hY3RpdmVQYXRoKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnQWxyZWFkeSBhdCBkZXN0aW5hdGlvbiwgcmVmcmVzaCBuYXZpZ2F0aW9uJyk7XG5cdFx0XHRyZXR1cm4gdGhpcy5hY3RpdmVTY3JlZW47XG5cdFx0fVxuXHRcdC8qIGpzaGludCBuZXdjYXA6IGZhbHNlICovXG5cdFx0dmFyIHNjcmVlbiA9IHRoaXMuc2NyZWVuc1twYXRoXTtcblx0XHRpZiAoIXNjcmVlbikge1xuXHRcdFx0dmFyIGhhbmRsZXIgPSByb3V0ZS5nZXRIYW5kbGVyKCk7XG5cdFx0XHRpZiAoaGFuZGxlciA9PT0gU2NyZWVuIHx8IFNjcmVlbi5pc0ltcGxlbWVudGVkQnkoaGFuZGxlci5wcm90b3R5cGUpKSB7XG5cdFx0XHRcdHNjcmVlbiA9IG5ldyBoYW5kbGVyKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzY3JlZW4gPSBoYW5kbGVyKHJvdXRlKSB8fCBuZXcgU2NyZWVuKCk7XG5cdFx0XHR9XG5cdFx0XHRjb25zb2xlLmxvZygnQ3JlYXRlIHNjcmVlbiBmb3IgWycgKyBwYXRoICsgJ10gWycgKyBzY3JlZW4gKyAnXScpO1xuXHRcdH1cblx0XHRyZXR1cm4gc2NyZWVuO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0aWYgKHRoaXMuYWN0aXZlU2NyZWVuKSB7XG5cdFx0XHR0aGlzLnJlbW92ZVNjcmVlbih0aGlzLmFjdGl2ZVBhdGgpO1xuXHRcdH1cblx0XHR0aGlzLmNsZWFyU2NyZWVuc0NhY2hlKCk7XG5cdFx0dGhpcy5mb3JtRXZlbnRIYW5kbGVyXy5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdHRoaXMubGlua0V2ZW50SGFuZGxlcl8ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR0aGlzLmFwcEV2ZW50SGFuZGxlcnNfLnJlbW92ZUFsbExpc3RlbmVycygpO1xuXHRcdHN1cGVyLmRpc3Bvc2VJbnRlcm5hbCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3BhdGNoZXMgdG8gdGhlIGZpcnN0IHJvdXRlIGhhbmRsZXIgdGhhdCBtYXRjaGVzIHRoZSBjdXJyZW50IHBhdGgsIGlmXG5cdCAqIGFueS5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfSBSZXR1cm5zIGEgcGVuZGluZyByZXF1ZXN0IGNhbmNlbGxhYmxlIHByb21pc2UuXG5cdCAqL1xuXHRkaXNwYXRjaCgpIHtcblx0XHRyZXR1cm4gdGhpcy5uYXZpZ2F0ZSh1dGlscy5nZXRDdXJyZW50QnJvd3NlclBhdGgoKSwgdHJ1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogU3RhcnRzIG5hdmlnYXRpb24gdG8gYSBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmVwbGFjZUhpc3RvcnkgUmVwbGFjZXMgYnJvd3NlciBoaXN0b3J5LlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IFJldHVybnMgYSBwZW5kaW5nIHJlcXVlc3QgY2FuY2VsbGFibGUgcHJvbWlzZS5cblx0ICovXG5cdGRvTmF2aWdhdGVfKHBhdGgsIG9wdF9yZXBsYWNlSGlzdG9yeSkge1xuXHRcdHZhciByb3V0ZSA9IHRoaXMuZmluZFJvdXRlKHBhdGgpO1xuXHRcdGlmICghcm91dGUpIHtcblx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gQ2FuY2VsbGFibGVQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yKCdObyByb3V0ZSBmb3IgJyArIHBhdGgpKTtcblx0XHRcdHJldHVybiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZTtcblx0XHR9XG5cblx0XHRjb25zb2xlLmxvZygnTmF2aWdhdGUgdG8gWycgKyBwYXRoICsgJ10nKTtcblxuXHRcdHRoaXMuc3RvcFBlbmRpbmdOYXZpZ2F0ZV8oKTtcblx0XHR0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgPSB0cnVlO1xuXG5cdFx0dmFyIG5leHRTY3JlZW4gPSB0aGlzLmNyZWF0ZVNjcmVlbkluc3RhbmNlKHBhdGgsIHJvdXRlKTtcblxuXHRcdHJldHVybiB0aGlzLm1heWJlUHJldmVudERlYWN0aXZhdGVfKClcblx0XHRcdC50aGVuKCgpID0+IHRoaXMubWF5YmVQcmV2ZW50QWN0aXZhdGVfKG5leHRTY3JlZW4pKVxuXHRcdFx0LnRoZW4oKCkgPT4gbmV4dFNjcmVlbi5sb2FkKHBhdGgpKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHQvLyBBdCB0aGlzIHBvaW50IHdlIGNhbm5vdCBzdG9wIG5hdmlnYXRpb24gYW5kIGFsbCByZWNlaXZlZFxuXHRcdFx0XHQvLyBuYXZpZ2F0ZSBjYW5kaWRhdGVzIHdpbGwgYmUgcXVldWVkIGF0IHNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZS5cblx0XHRcdFx0dGhpcy5uYXZpZ2F0aW9uU3RyYXRlZ3kgPSBOYXZpZ2F0aW9uU3RyYXRlZ3kuU0NIRURVTEVfTEFTVDtcblxuXHRcdFx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4pIHtcblx0XHRcdFx0XHR0aGlzLmFjdGl2ZVNjcmVlbi5kZWFjdGl2YXRlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5wcmVwYXJlTmF2aWdhdGVIaXN0b3J5XyhwYXRoLCBuZXh0U2NyZWVuLCBvcHRfcmVwbGFjZUhpc3RvcnkpO1xuXHRcdFx0XHR0aGlzLnByZXBhcmVOYXZpZ2F0ZVN1cmZhY2VzXyhcblx0XHRcdFx0XHRuZXh0U2NyZWVuLFxuXHRcdFx0XHRcdHRoaXMuc3VyZmFjZXMsXG5cdFx0XHRcdFx0dGhpcy5leHRyYWN0UGFyYW1zKHJvdXRlLCBwYXRoKVxuXHRcdFx0XHQpO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuKCgpID0+IG5leHRTY3JlZW4uZXZhbHVhdGVTdHlsZXModGhpcy5zdXJmYWNlcykpXG5cdFx0XHQudGhlbigoKSA9PiBuZXh0U2NyZWVuLmZsaXAodGhpcy5zdXJmYWNlcykpXG5cdFx0XHQudGhlbigoKSA9PiBuZXh0U2NyZWVuLmV2YWx1YXRlU2NyaXB0cyh0aGlzLnN1cmZhY2VzKSlcblx0XHRcdC50aGVuKCgpID0+IHRoaXMubWF5YmVVcGRhdGVTY3JvbGxQb3NpdGlvblN0YXRlXygpKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5zeW5jU2Nyb2xsUG9zaXRpb25TeW5jVGhlbkFzeW5jXygpKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5maW5hbGl6ZU5hdmlnYXRlXyhwYXRoLCBuZXh0U2NyZWVuKSlcblx0XHRcdC50aGVuKCgpID0+IHRoaXMubWF5YmVPdmVybG9hZEJlZm9yZVVubG9hZF8oKSlcblx0XHRcdC5jYXRjaCgocmVhc29uKSA9PiB7XG5cdFx0XHRcdHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLmhhbmRsZU5hdmlnYXRlRXJyb3JfKHBhdGgsIG5leHRTY3JlZW4sIHJlYXNvbik7XG5cdFx0XHRcdHRocm93IHJlYXNvbjtcblx0XHRcdH0pXG5cdFx0XHQudGhlbkFsd2F5cygoKSA9PiB7XG5cdFx0XHRcdHRoaXMubmF2aWdhdGlvblN0cmF0ZWd5ID0gTmF2aWdhdGlvblN0cmF0ZWd5LklNTUVESUFURTtcblxuXHRcdFx0XHRpZiAodGhpcy5zY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUubGVuZ3RoKSB7XG5cdFx0XHRcdFx0Y29uc3Qgc2NoZWR1bGVkTmF2aWdhdGlvbiA9IHRoaXMuc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLnNoaWZ0KCk7XG5cdFx0XHRcdFx0dGhpcy5tYXliZU5hdmlnYXRlXyhzY2hlZHVsZWROYXZpZ2F0aW9uLmhyZWYsIHNjaGVkdWxlZE5hdmlnYXRpb24pO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyBwYXJhbXMgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBwYXRoIGFuZCByb3V0ZS5cblx0ICogQHBhcmFtIHshUm91dGV9IHJvdXRlXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG5cdCAqIEBwYXJhbSB7IU9iamVjdH1cblx0ICovXG5cdGV4dHJhY3RQYXJhbXMocm91dGUsIHBhdGgpIHtcblx0XHRyZXR1cm4gcm91dGUuZXh0cmFjdFBhcmFtcyh0aGlzLmdldFJvdXRlUGF0aChwYXRoKSk7XG5cdH1cblxuXHQvKipcblx0ICogRmluYWxpemVzIGEgc2NyZWVuIG5hdmlnYXRpb24uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEBwYXJhbSB7IVNjcmVlbn0gbmV4dFNjcmVlblxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRmaW5hbGl6ZU5hdmlnYXRlXyhwYXRoLCBuZXh0U2NyZWVuKSB7XG5cdFx0bmV4dFNjcmVlbi5hY3RpdmF0ZSgpO1xuXG5cdFx0aWYgKHRoaXMuYWN0aXZlU2NyZWVuICYmICF0aGlzLmFjdGl2ZVNjcmVlbi5pc0NhY2hlYWJsZSgpKSB7XG5cdFx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4gIT09IG5leHRTY3JlZW4pIHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTY3JlZW4odGhpcy5hY3RpdmVQYXRoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLmFjdGl2ZVBhdGggPSBwYXRoO1xuXHRcdHRoaXMuYWN0aXZlU2NyZWVuID0gbmV4dFNjcmVlbjtcblx0XHR0aGlzLmJyb3dzZXJQYXRoQmVmb3JlTmF2aWdhdGUgPSB1dGlscy5nZXRDdXJyZW50QnJvd3NlclBhdGhXaXRob3V0SGFzaCgpO1xuXHRcdHRoaXMuc2NyZWVuc1twYXRoXSA9IG5leHRTY3JlZW47XG5cdFx0dGhpcy5pc05hdmlnYXRpb25QZW5kaW5nID0gZmFsc2U7XG5cdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBudWxsO1xuXHRcdGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCA9IG51bGw7XG5cdFx0Z2xvYmFscy5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50ID0gbnVsbDtcblx0XHRjb25zb2xlLmxvZygnTmF2aWdhdGlvbiBkb25lJyk7XG5cdH1cblxuXHQvKipcblx0ICogRmluZHMgYSByb3V0ZSBmb3IgdGhlIHRlc3QgcGF0aC4gUmV0dXJucyB0cnVlIGlmIG1hdGNoZXMgaGFzIGEgcm91dGUsXG5cdCAqIG90aGVyd2lzZSByZXR1cm5zIG51bGwuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEByZXR1cm4gez9PYmplY3R9IFJvdXRlIGhhbmRsZXIgaWYgbWF0Y2ggYW55IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZVxuXHQgKiAgICAgcGF0aCBpcyB0aGUgc2FtZSBhcyB0aGUgY3VycmVudCB1cmwgYW5kIHRoZSBwYXRoIGNvbnRhaW5zIGEgZnJhZ21lbnQuXG5cdCAqL1xuXHRmaW5kUm91dGUocGF0aCkge1xuXHRcdHBhdGggPSB0aGlzLmdldFJvdXRlUGF0aChwYXRoKTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucm91dGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgcm91dGUgPSB0aGlzLnJvdXRlc1tpXTtcblx0XHRcdGlmIChyb3V0ZS5tYXRjaGVzUGF0aChwYXRoKSkge1xuXHRcdFx0XHRyZXR1cm4gcm91dGU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBhbGxvdyBwcmV2ZW50IG5hdmlnYXRlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Z2V0QWxsb3dQcmV2ZW50TmF2aWdhdGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWxsb3dQcmV2ZW50TmF2aWdhdGU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBsaW5rIGJhc2UgcGF0aC5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldEJhc2VQYXRoKCkge1xuXHRcdHJldHVybiB0aGlzLmJhc2VQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGRlZmF1bHQgcGFnZSB0aXRsZS5cblx0ICogQHJldHVybiB7c3RyaW5nfSBkZWZhdWx0VGl0bGVcblx0ICovXG5cdGdldERlZmF1bHRUaXRsZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5kZWZhdWx0VGl0bGU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZm9ybSBzZWxlY3Rvci5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldEZvcm1TZWxlY3RvcigpIHtcblx0XHRyZXR1cm4gdGhpcy5mb3JtU2VsZWN0b3I7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2sgaWYgcm91dGUgbWF0Y2hpbmcgaXMgaWdub3JpbmcgcXVlcnkgc3RyaW5nIGZyb20gdGhlIHJvdXRlIHBhdGguXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRnZXRJZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGgoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGxpbmsgc2VsZWN0b3IuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRMaW5rU2VsZWN0b3IoKSB7XG5cdFx0cmV0dXJuIHRoaXMubGlua1NlbGVjdG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGxvYWRpbmcgY3NzIGNsYXNzLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0TG9hZGluZ0Nzc0NsYXNzKCkge1xuXHRcdHJldHVybiB0aGlzLmxvYWRpbmdDc3NDbGFzcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBnaXZlbiBwYXRoIGZvcm1hdHRlZCB0byBiZSBtYXRjaGVkIGJ5IGEgcm91dGUuIFRoaXMgd2lsbCxcblx0ICogZm9yIGV4YW1wbGUsIHJlbW92ZSB0aGUgYmFzZSBwYXRoIGZyb20gaXQsIGJ1dCBtYWtlIHN1cmUgaXQgd2lsbCBlbmRcblx0ICogd2l0aCBhICcvJy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0Um91dGVQYXRoKHBhdGgpIHtcblx0XHRpZiAodGhpcy5nZXRJZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGgoKSkge1xuXHRcdFx0cGF0aCA9IHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaChwYXRoKTtcblx0XHRcdHJldHVybiB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2hBbmRTZWFyY2gocGF0aC5zdWJzdHIodGhpcy5iYXNlUGF0aC5sZW5ndGgpKTtcblx0XHR9XG5cblx0XHRwYXRoID0gdXRpbHMuZ2V0VXJsUGF0aFdpdGhvdXRIYXNoKHBhdGgpO1xuXHRcdHJldHVybiB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2gocGF0aC5zdWJzdHIodGhpcy5iYXNlUGF0aC5sZW5ndGgpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSB1cGRhdGUgc2Nyb2xsIHBvc2l0aW9uIHZhbHVlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Z2V0VXBkYXRlU2Nyb2xsUG9zaXRpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMudXBkYXRlU2Nyb2xsUG9zaXRpb247XG5cdH1cblxuXHQvKipcblx0ICogSGFuZGxlIG5hdmlnYXRpb24gZXJyb3IuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEBwYXJhbSB7IVNjcmVlbn0gbmV4dFNjcmVlblxuXHQgKiBAcGFyYW0geyFFcnJvcn0gZXJyb3Jcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0aGFuZGxlTmF2aWdhdGVFcnJvcl8ocGF0aCwgbmV4dFNjcmVlbiwgZXJyb3IpIHtcblx0XHRjb25zb2xlLmxvZygnTmF2aWdhdGlvbiBlcnJvciBmb3IgWycgKyBuZXh0U2NyZWVuICsgJ10gKCcgKyBlcnJvci5zdGFjayArICcpJyk7XG5cdFx0dGhpcy5lbWl0KCduYXZpZ2F0aW9uRXJyb3InLCB7XG5cdFx0XHRlcnJvcixcblx0XHRcdG5leHRTY3JlZW4sXG5cdFx0XHRwYXRoXG5cdFx0fSk7XG5cdFx0aWYgKCF1dGlscy5pc0N1cnJlbnRCcm93c2VyUGF0aChwYXRoKSkge1xuXHRcdFx0aWYgKHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyAmJiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZSkge1xuXHRcdFx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZS50aGVuQWx3YXlzKCgpID0+IHRoaXMucmVtb3ZlU2NyZWVuKHBhdGgpLCB0aGlzKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMucmVtb3ZlU2NyZWVuKHBhdGgpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgYXBwIGhhcyByb3V0ZXMuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRoYXNSb3V0ZXMoKSB7XG5cdFx0cmV0dXJuIHRoaXMucm91dGVzLmxlbmd0aCA+IDA7XG5cdH1cblxuXHQvKipcblx0ICogVGVzdHMgaWYgaG9zdCBpcyBhbiBvZmZzaXRlIGxpbmsuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaG9zdCBMaW5rIGhvc3QgdG8gY29tcGFyZSB3aXRoXG5cdCAqICAgICA8Y29kZT5nbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ob3N0PC9jb2RlPi5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0aXNMaW5rU2FtZU9yaWdpbl8oaG9zdCkge1xuXHRcdGNvbnN0IGhvc3RVcmkgPSBuZXcgVXJpKGhvc3QpO1xuXHRcdGNvbnN0IGxvY2F0aW9uSG9zdFVyaSA9IG5ldyBVcmkoZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaG9zdCk7XG5cblx0XHRyZXR1cm4gaG9zdFVyaS5nZXRQb3J0KCkgPT09IGxvY2F0aW9uSG9zdFVyaS5nZXRQb3J0KCkgJiYgaG9zdFVyaS5nZXRIb3N0bmFtZSgpID09PSBsb2NhdGlvbkhvc3RVcmkuZ2V0SG9zdG5hbWUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUZXN0cyBpZiBsaW5rIGVsZW1lbnQgaGFzIHRoZSBzYW1lIGFwcCdzIGJhc2UgcGF0aC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIExpbmsgcGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRpc1NhbWVCYXNlUGF0aF8ocGF0aCkge1xuXHRcdHJldHVybiBwYXRoLmluZGV4T2YodGhpcy5iYXNlUGF0aCkgPT09IDA7XG5cdH1cblxuXHQvKipcblx0ICogTG9jayB0aGUgZG9jdW1lbnQgc2Nyb2xsIGluIG9yZGVyIHRvIGF2b2lkIHRoZSBicm93c2VyIG5hdGl2ZSBiYWNrIGFuZFxuXHQgKiBmb3J3YXJkIG5hdmlnYXRpb24gdG8gY2hhbmdlIHRoZSBzY3JvbGwgcG9zaXRpb24uIEluIHRoZSBlbmQgb2Zcblx0ICogbmF2aWdhdGlvbiBsaWZlY3ljbGUgc2Nyb2xsIGlzIHJlcG9zaXRpb25lZC5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0bG9ja0hpc3RvcnlTY3JvbGxQb3NpdGlvbl8oKSB7XG5cdFx0dmFyIHN0YXRlID0gZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5zdGF0ZTtcblx0XHRpZiAoIXN0YXRlKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdC8vIEJyb3dzZXJzIGFyZSBpbmNvbnNpc3RlbnQgd2hlbiByZS1wb3NpdGlvbmluZyB0aGUgc2Nyb2xsIGhpc3Rvcnkgb25cblx0XHQvLyBwb3BzdGF0ZS4gQXQgc29tZSBicm93c2VycywgaGlzdG9yeSBzY3JvbGwgaGFwcGVucyBiZWZvcmUgcG9wc3RhdGUsIHRoZW5cblx0XHQvLyBsb2NrIHRoZSBzY3JvbGwgb24gdGhlIGxhc3Qga25vd24gcG9zaXRpb24gYXMgc29vbiBhcyBwb3NzaWJsZSBhZnRlciB0aGVcblx0XHQvLyBjdXJyZW50IEpTIGV4ZWN1dGlvbiBjb250ZXh0IGFuZCBjYXB0dXJlIHRoZSBjdXJyZW50IHZhbHVlLiBTb21lIG90aGVycyxcblx0XHQvLyBoaXN0b3J5IHNjcm9sbCBoYXBwZW5zIGFmdGVyIHBvcHN0YXRlLCBpbiB0aGlzIGNhc2UsIHdlIGJpbmQgYW4gb25jZVxuXHRcdC8vIHNjcm9sbCBldmVudCB0byBsb2NrIHRoZSBsYXMga25vd24gcG9zaXRpb24uIExhc3RseSwgdGhlIHByZXZpb3VzIHR3b1xuXHRcdC8vIGJlaGF2aW9ycyBjYW4gaGFwcGVuIGV2ZW4gb24gdGhlIHNhbWUgYnJvd3NlciwgaGVuY2UgdGhlIHJhY2Ugd2lsbCBkZWNpZGVcblx0XHQvLyB0aGUgd2lubmVyLlxuXHRcdHZhciB3aW5uZXIgPSBmYWxzZTtcblx0XHR2YXIgc3dpdGNoU2Nyb2xsUG9zaXRpb25SYWNlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRnbG9iYWxzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHN3aXRjaFNjcm9sbFBvc2l0aW9uUmFjZSwgZmFsc2UpO1xuXHRcdFx0aWYgKCF3aW5uZXIpIHtcblx0XHRcdFx0Z2xvYmFscy53aW5kb3cuc2Nyb2xsVG8oc3RhdGUuc2Nyb2xsTGVmdCwgc3RhdGUuc2Nyb2xsVG9wKTtcblx0XHRcdFx0d2lubmVyID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdGFzeW5jLm5leHRUaWNrKHN3aXRjaFNjcm9sbFBvc2l0aW9uUmFjZSk7XG5cdFx0Z2xvYmFscy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBzd2l0Y2hTY3JvbGxQb3NpdGlvblJhY2UsIGZhbHNlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBJZiBzdXBwb3J0ZWQgYnkgdGhlIGJyb3dzZXIsIGRpc2FibGVzIG5hdGl2ZSBzY3JvbGwgcmVzdG9yYXRpb24gYW5kXG5cdCAqIHN0b3JlcyBjdXJyZW50IHZhbHVlLlxuXHQgKi9cblx0bWF5YmVEaXNhYmxlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb24oKSB7XG5cdFx0aWYgKHRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25TdXBwb3J0ZWQpIHtcblx0XHRcdHRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25fID0gZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbjtcblx0XHRcdGdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSAnbWFudWFsJztcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBldmFsdWF0ZSBpZiBpcyBwb3NzaWJsZSB0byBxdWV1ZSByZWNlaXZlZFxuXHQgKiAgZG9tIGV2ZW50IHRvIHNjaGVkdWxlTmF2aWdhdGlvblF1ZXVlIGFuZCBlbnF1ZXVlIGl0LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaHJlZiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgbGluaydzIGhyZWYuXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IERvbSBldmVudCB0aGF0IGluaXRpYXRlZCB0aGUgbmF2aWdhdGlvbi5cblx0ICovXG5cdG1heWJlU2NoZWR1bGVOYXZpZ2F0aW9uXyhocmVmLCBldmVudCkge1xuXHRcdGlmICh0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgJiYgdGhpcy5uYXZpZ2F0aW9uU3RyYXRlZ3kgPT09IE5hdmlnYXRpb25TdHJhdGVneS5TQ0hFRFVMRV9MQVNUKSB7XG5cdFx0XHR0aGlzLnNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZSA9IFtvYmplY3QubWl4aW4oe1xuXHRcdFx0XHRocmVmLFxuXHRcdFx0XHRpc1NjaGVkdWxlZE5hdmlnYXRpb246IHRydWVcblx0XHRcdH0sIGV2ZW50KV07XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIG5hdmlnYXRlIHRvIGEgcGF0aC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgSW5mb3JtYXRpb24gYWJvdXQgdGhlIGxpbmsncyBocmVmLlxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudCBEb20gZXZlbnQgdGhhdCBpbml0aWF0ZWQgdGhlIG5hdmlnYXRpb24uXG5cdCAqL1xuXHRtYXliZU5hdmlnYXRlXyhocmVmLCBldmVudCkge1xuXHRcdGlmICghdGhpcy5jYW5OYXZpZ2F0ZShocmVmKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGlzTmF2aWdhdGlvblNjaGVkdWxlZCA9IHRoaXMubWF5YmVTY2hlZHVsZU5hdmlnYXRpb25fKGhyZWYsIGV2ZW50KTtcblxuXHRcdGlmIChpc05hdmlnYXRpb25TY2hlZHVsZWQpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIG5hdmlnYXRlRmFpbGVkID0gZmFsc2U7XG5cdFx0dHJ5IHtcblx0XHRcdHRoaXMubmF2aWdhdGUodXRpbHMuZ2V0VXJsUGF0aChocmVmKSwgZmFsc2UsIGV2ZW50KTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdC8vIERvIG5vdCBwcmV2ZW50IGxpbmsgbmF2aWdhdGlvbiBpbiBjYXNlIHNvbWUgc3luY2hyb25vdXMgZXJyb3Igb2NjdXJzXG5cdFx0XHRuYXZpZ2F0ZUZhaWxlZCA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKCFuYXZpZ2F0ZUZhaWxlZCAmJiAhZXZlbnQuaXNTY2hlZHVsZWROYXZpZ2F0aW9uKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3Mgd2hldGhlciB0aGUgb25iZWZvcmV1bmxvYWQgZ2xvYmFsIGV2ZW50IGhhbmRsZXIgaXMgb3ZlcmxvYWRlZFxuXHQgKiBieSBjbGllbnQgY29kZS4gSWYgc28sIGl0IHJlcGxhY2VzIHdpdGggYSBmdW5jdGlvbiB0aGF0IGhhbHRzIHRoZSBub3JtYWxcblx0ICogZXZlbnQgZmxvdyBpbiByZWxhdGlvbiB3aXRoIHRoZSBjbGllbnQgb25iZWZvcmV1bmxvYWQgZnVuY3Rpb24uXG5cdCAqIFRoaXMgY2FuIGJlIGluIG1vc3QgcGFydCB1c2VkIHRvIHByZW1hdHVyZWx5IHRlcm1pbmF0ZSBuYXZpZ2F0aW9uIHRvIG90aGVyIHBhZ2VzXG5cdCAqIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gY29uc3RyYWl0KHMpLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXliZU92ZXJsb2FkQmVmb3JlVW5sb2FkXygpIHtcblx0XHRpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIHdpbmRvdy5vbmJlZm9yZXVubG9hZCkge1xuXHRcdFx0d2luZG93Ll9vbmJlZm9yZXVubG9hZCA9IHdpbmRvdy5vbmJlZm9yZXVubG9hZDtcblxuXHRcdFx0d2luZG93Lm9uYmVmb3JldW5sb2FkID0gZXZlbnQgPT4ge1xuXHRcdFx0XHR0aGlzLmVtaXQoJ2JlZm9yZVVubG9hZCcsIGV2ZW50KTtcblx0XHRcdFx0aWYgKGV2ZW50ICYmIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdFx0Ly8gbWFyayB0aGUgdXBkYXRlZCBoYW5kbGVyIGR1ZSB1bndhbnRlZCByZWN1cnNpb25cblx0XHRcdHdpbmRvdy5vbmJlZm9yZXVubG9hZC5fb3ZlcmxvYWRlZCA9IHRydWU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENhbmNlbHMgbmF2aWdhdGlvbiBpZiBuZXh0U2NyZWVuJ3MgYmVmb3JlQWN0aXZhdGUgbGlmZWN5Y2xlIG1ldGhvZFxuXHQgKiByZXNvbHZlcyB0byB0cnVlLlxuXHQgKiBAcGFyYW0geyFTY3JlZW59IG5leHRTY3JlZW5cblx0ICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX1cblx0ICovXG5cdG1heWJlUHJldmVudEFjdGl2YXRlXyhuZXh0U2NyZWVuKSB7XG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKClcblx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0cmV0dXJuIG5leHRTY3JlZW4uYmVmb3JlQWN0aXZhdGUoKTtcblx0XHRcdH0pXG5cdFx0XHQudGhlbihwcmV2ZW50ID0+IHtcblx0XHRcdFx0aWYgKHByZXZlbnQpIHtcblx0XHRcdFx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IENhbmNlbGxhYmxlUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxhYmxlUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvcignQ2FuY2VsbGVkIGJ5IG5leHQgc2NyZWVuJykpO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FuY2VscyBuYXZpZ2F0aW9uIGlmIGFjdGl2ZVNjcmVlbidzIGJlZm9yZURlYWN0aXZhdGUgbGlmZWN5Y2xlXG5cdCAqIG1ldGhvZCByZXNvbHZlcyB0byB0cnVlLlxuXHQgKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlfVxuXHQgKi9cblx0bWF5YmVQcmV2ZW50RGVhY3RpdmF0ZV8oKSB7XG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKClcblx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0aWYgKHRoaXMuYWN0aXZlU2NyZWVuKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuYWN0aXZlU2NyZWVuLmJlZm9yZURlYWN0aXZhdGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC50aGVuKHByZXZlbnQgPT4ge1xuXHRcdFx0XHRpZiAocHJldmVudCkge1xuXHRcdFx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gQ2FuY2VsbGFibGVQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yKCdDYW5jZWxsZWQgYnkgYWN0aXZlIHNjcmVlbicpKTtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5wZW5kaW5nTmF2aWdhdGU7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHJlcG9zaXRpb24gc2Nyb2xsIHRvIGhhc2hlZCBhbmNob3IuXG5cdCAqL1xuXHRtYXliZVJlcG9zaXRpb25TY3JvbGxUb0hhc2hlZEFuY2hvcigpIHtcblx0XHRjb25zdCBoYXNoID0gZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaGFzaDtcblx0XHRpZiAoaGFzaCkge1xuXHRcdFx0bGV0IGFuY2hvckVsZW1lbnQgPSBnbG9iYWxzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGhhc2guc3Vic3RyaW5nKDEpKTtcblx0XHRcdGlmIChhbmNob3JFbGVtZW50KSB7XG5cdFx0XHRcdGNvbnN0IHtvZmZzZXRMZWZ0LCBvZmZzZXRUb3B9ID0gdXRpbHMuZ2V0Tm9kZU9mZnNldChhbmNob3JFbGVtZW50KTtcblx0XHRcdFx0Z2xvYmFscy53aW5kb3cuc2Nyb2xsVG8ob2Zmc2V0TGVmdCwgb2Zmc2V0VG9wKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogSWYgc3VwcG9ydGVkIGJ5IHRoZSBicm93c2VyLCByZXN0b3JlcyBuYXRpdmUgc2Nyb2xsIHJlc3RvcmF0aW9uIHRvIHRoZVxuXHQgKiB2YWx1ZSBjYXB0dXJlZCBieSBgbWF5YmVEaXNhYmxlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25gLlxuXHQgKi9cblx0bWF5YmVSZXN0b3JlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb24oKSB7XG5cdFx0aWYgKHRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25TdXBwb3J0ZWQgJiYgdGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvbl8pIHtcblx0XHRcdGdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSB0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uXztcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgcmVzdG9yZSByZWRpcmVjdGVkIHBhdGggaGFzaCBpbiBjYXNlIGJvdGggdGhlIGN1cnJlbnQgcGF0aCBhbmRcblx0ICogdGhlIGdpdmVuIHBhdGggYXJlIHRoZSBzYW1lLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBiZWZvcmUgbmF2aWdhdGlvbi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSByZWRpcmVjdFBhdGggUGF0aCBhZnRlciBuYXZpZ2F0aW9uLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGhhc2ggSGFzaCB0byBiZSBhZGRlZCB0byB0aGUgcGF0aC5cblx0ICogQHJldHVybiB7IXN0cmluZ30gUmV0dXJucyB0aGUgcGF0aCB3aXRoIHRoZSBoYXNoIHJlc3RvcmVkLlxuXHQgKi9cblx0bWF5YmVSZXN0b3JlUmVkaXJlY3RQYXRoSGFzaF8ocGF0aCwgcmVkaXJlY3RQYXRoLCBoYXNoKSB7XG5cdFx0aWYgKHJlZGlyZWN0UGF0aCA9PT0gdXRpbHMuZ2V0VXJsUGF0aFdpdGhvdXRIYXNoKHBhdGgpKSB7XG5cdFx0XHRyZXR1cm4gcmVkaXJlY3RQYXRoICsgaGFzaDtcblx0XHR9XG5cdFx0cmV0dXJuIHJlZGlyZWN0UGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSB1cGRhdGUgc2Nyb2xsIHBvc2l0aW9uIGluIGhpc3Rvcnkgc3RhdGUgdG8gYW5jaG9yIG9uIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgYW5jaG9yXG5cdCAqL1xuXHRtYXliZVVwZGF0ZVNjcm9sbFBvc2l0aW9uU3RhdGVfKCkge1xuXHRcdHZhciBoYXNoID0gZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaGFzaDtcblx0XHR2YXIgYW5jaG9yRWxlbWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGFzaC5zdWJzdHJpbmcoMSkpO1xuXHRcdGlmIChhbmNob3JFbGVtZW50KSB7XG5cdFx0XHRjb25zdCB7b2Zmc2V0TGVmdCwgb2Zmc2V0VG9wfSA9IHV0aWxzLmdldE5vZGVPZmZzZXQoYW5jaG9yRWxlbWVudCk7XG5cdFx0XHR0aGlzLnNhdmVIaXN0b3J5Q3VycmVudFBhZ2VTY3JvbGxQb3NpdGlvbl8ob2Zmc2V0VG9wLCBvZmZzZXRMZWZ0KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTmF2aWdhdGVzIHRvIHRoZSBzcGVjaWZpZWQgcGF0aCBpZiB0aGVyZSBpcyBhIHJvdXRlIGhhbmRsZXIgdGhhdCBtYXRjaGVzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCB0byBuYXZpZ2F0ZSBjb250YWluaW5nIHRoZSBiYXNlIHBhdGguXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZXBsYWNlSGlzdG9yeSBSZXBsYWNlcyBicm93c2VyIGhpc3RvcnkuXG5cdCAqIEBwYXJhbSB7RXZlbnQ9fSBldmVudCBPcHRpb25hbCBldmVudCBvYmplY3QgdGhhdCB0cmlnZ2VyZWQgdGhlIG5hdmlnYXRpb24uXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUmV0dXJucyBhIHBlbmRpbmcgcmVxdWVzdCBjYW5jZWxsYWJsZSBwcm9taXNlLlxuXHQgKi9cblx0bmF2aWdhdGUocGF0aCwgb3B0X3JlcGxhY2VIaXN0b3J5LCBvcHRfZXZlbnQpIHtcblx0XHRpZiAoIXV0aWxzLmlzSHRtbDVIaXN0b3J5U3VwcG9ydGVkKCkpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignSFRNTDUgSGlzdG9yeSBpcyBub3Qgc3VwcG9ydGVkLiBTZW5uYSB3aWxsIG5vdCBpbnRlcmNlcHQgbmF2aWdhdGlvbi4nKTtcblx0XHR9XG5cblx0XHRpZiAob3B0X2V2ZW50KSB7XG5cdFx0XHRnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQgPSBvcHRfZXZlbnQuY2FwdHVyZWRGb3JtRWxlbWVudDtcblx0XHRcdGdsb2JhbHMuY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudCA9IG9wdF9ldmVudC5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50O1xuXHRcdH1cblxuXHRcdC8vIFdoZW4gcmVsb2FkaW5nIHRoZSBzYW1lIHBhdGggZG8gcmVwbGFjZVN0YXRlIGluc3RlYWQgb2YgcHVzaFN0YXRlIHRvXG5cdFx0Ly8gYXZvaWQgcG9sbHV0aW5nIGhpc3Rvcnkgd2l0aCBzdGF0ZXMgd2l0aCB0aGUgc2FtZSBwYXRoLlxuXHRcdGlmIChwYXRoID09PSB0aGlzLmFjdGl2ZVBhdGgpIHtcblx0XHRcdG9wdF9yZXBsYWNlSGlzdG9yeSA9IHRydWU7XG5cdFx0fVxuXG5cdFx0dGhpcy5lbWl0KCdiZWZvcmVOYXZpZ2F0ZScsIHtcblx0XHRcdGV2ZW50OiBvcHRfZXZlbnQsXG5cdFx0XHRwYXRoOiBwYXRoLFxuXHRcdFx0cmVwbGFjZUhpc3Rvcnk6ICEhb3B0X3JlcGxhY2VIaXN0b3J5XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gdGhpcy5wZW5kaW5nTmF2aWdhdGU7XG5cdH1cblxuXHQvKipcblx0ICogQmVmb3JlcyBuYXZpZ2F0aW9uIHRvIGEgcGF0aC5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IEV2ZW50IGZhY2FkZSBjb250YWluaW5nIDxjb2RlPnBhdGg8L2NvZGU+IGFuZFxuXHQgKiAgICAgPGNvZGU+cmVwbGFjZUhpc3Rvcnk8L2NvZGU+LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvbkJlZm9yZU5hdmlnYXRlXyhldmVudCkge1xuXHRcdGlmIChnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQpIHtcblx0XHRcdGV2ZW50LmZvcm0gPSBnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQ7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEJlZm9yZXMgbmF2aWdhdGlvbiB0byBhIHBhdGguIFJ1bnMgYWZ0ZXIgZXh0ZXJuYWwgbGlzdGVuZXJzLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlIGNvbnRhaW5pbmcgPGNvZGU+cGF0aDwvY29kZT4gYW5kXG5cdCAqICAgICA8Y29kZT5yZXBsYWNlSGlzdG9yeTwvY29kZT4uXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uQmVmb3JlTmF2aWdhdGVEZWZhdWx0XyhldmVudCkge1xuXHRcdGlmICh0aGlzLnBlbmRpbmdOYXZpZ2F0ZSkge1xuXHRcdFx0aWYgKHRoaXMucGVuZGluZ05hdmlnYXRlLnBhdGggPT09IGV2ZW50LnBhdGggfHwgdGhpcy5uYXZpZ2F0aW9uU3RyYXRlZ3kgPT09IE5hdmlnYXRpb25TdHJhdGVneS5TQ0hFRFVMRV9MQVNUKSB7XG5cdFx0XHRcdGNvbnNvbGUubG9nKCdXYWl0aW5nLi4uJyk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLmVtaXQoJ2JlZm9yZVVubG9hZCcsIGV2ZW50KTtcblxuXHRcdHRoaXMuZW1pdCgnc3RhcnROYXZpZ2F0ZScsIHtcblx0XHRcdGZvcm06IGV2ZW50LmZvcm0sXG5cdFx0XHRwYXRoOiBldmVudC5wYXRoLFxuXHRcdFx0cmVwbGFjZUhpc3Rvcnk6IGV2ZW50LnJlcGxhY2VIaXN0b3J5XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQ3VzdG9tIGV2ZW50IGhhbmRsZXIgdGhhdCBleGVjdXRlcyB0aGUgb3JpZ2luYWwgbGlzdGVuZXIgdGhhdCBoYXMgYmVlblxuXHQgKiBhZGRlZCBieSB0aGUgY2xpZW50IGNvZGUgYW5kIHRlcm1pbmF0ZXMgdGhlIG5hdmlnYXRpb24gYWNjb3JkaW5nbHkuXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBvcmlnaW5hbCBFdmVudCBmYWNhZGUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uQmVmb3JlVW5sb2FkRGVmYXVsdF8oZXZlbnQpIHtcblx0XHR2YXIgZnVuYyA9IHdpbmRvdy5fb25iZWZvcmV1bmxvYWQ7XG5cdFx0aWYgKGZ1bmMgJiYgIWZ1bmMuX292ZXJsb2FkZWQgJiYgZnVuYygpKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBJbnRlcmNlcHRzIGRvY3VtZW50IGNsaWNrcyBhbmQgdGVzdCBsaW5rIGVsZW1lbnRzIGluIG9yZGVyIHRvIGRlY2lkZVxuXHQgKiB3aGV0aGVyIFN1cmZhY2UgYXBwIGNhbiBuYXZpZ2F0ZS5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IEV2ZW50IGZhY2FkZVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvbkRvY0NsaWNrRGVsZWdhdGVfKGV2ZW50KSB7XG5cdFx0aWYgKGV2ZW50LmFsdEtleSB8fCBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQuYnV0dG9uKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnTmF2aWdhdGUgYWJvcnRlZCwgaW52YWxpZCBtb3VzZSBidXR0b24gb3IgbW9kaWZpZXIga2V5IHByZXNzZWQuJyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMubWF5YmVOYXZpZ2F0ZV8oZXZlbnQuZGVsZWdhdGVUYXJnZXQuaHJlZiwgZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEludGVyY2VwdHMgZG9jdW1lbnQgZm9ybSBzdWJtaXRzIGFuZCB0ZXN0IGFjdGlvbiBwYXRoIGluIG9yZGVyIHRvIGRlY2lkZVxuXHQgKiB3aGV0aGVyIFN1cmZhY2UgYXBwIGNhbiBuYXZpZ2F0ZS5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IEV2ZW50IGZhY2FkZVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvbkRvY1N1Ym1pdERlbGVnYXRlXyhldmVudCkge1xuXHRcdHZhciBmb3JtID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQ7XG5cdFx0aWYgKGZvcm0ubWV0aG9kID09PSAnZ2V0Jykge1xuXHRcdFx0Y29uc29sZS5sb2coJ0dFVCBtZXRob2Qgbm90IHN1cHBvcnRlZCcpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRldmVudC5jYXB0dXJlZEZvcm1FbGVtZW50ID0gZm9ybTtcblx0XHRjb25zdCBidXR0b25TZWxlY3RvciA9ICdidXR0b246bm90KFt0eXBlXSksYnV0dG9uW3R5cGU9c3VibWl0XSxpbnB1dFt0eXBlPXN1Ym1pdF0nO1xuXHRcdGlmIChtYXRjaChnbG9iYWxzLmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQsIGJ1dHRvblNlbGVjdG9yKSkge1xuXHRcdFx0ZXZlbnQuY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZXZlbnQuY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudCA9IGZvcm0ucXVlcnlTZWxlY3RvcihidXR0b25TZWxlY3Rvcik7XG5cdFx0fVxuXHRcdHRoaXMubWF5YmVOYXZpZ2F0ZV8oZm9ybS5hY3Rpb24sIGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBMaXN0ZW5zIHRvIHRoZSB3aW5kb3cncyBsb2FkIGV2ZW50IGluIG9yZGVyIHRvIGF2b2lkIGlzc3VlcyB3aXRoIHNvbWUgYnJvd3NlcnNcblx0ICogdGhhdCB0cmlnZ2VyIHBvcHN0YXRlIGNhbGxzIG9uIHRoZSBmaXJzdCBsb2FkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBzZWVcblx0ICogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82NDIxNzY5L3BvcHN0YXRlLW9uLXBhZ2VzLWxvYWQtaW4tY2hyb21lLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvbkxvYWRfKCkge1xuXHRcdHRoaXMuc2tpcExvYWRQb3BzdGF0ZSA9IHRydWU7XG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHQvLyBUaGUgdGltZW91dCBlbnN1cmVzIHRoYXQgcG9wc3RhdGUgZXZlbnRzIHdpbGwgYmUgdW5ibG9ja2VkIHJpZ2h0XG5cdFx0XHQvLyBhZnRlciB0aGUgbG9hZCBldmVudCBvY2N1cmVkLCBidXQgbm90IGluIHRoZSBzYW1lIGV2ZW50LWxvb3AgY3ljbGUuXG5cdFx0XHR0aGlzLnNraXBMb2FkUG9wc3RhdGUgPSBmYWxzZTtcblx0XHR9LCAwKTtcblx0XHQvLyBUcnkgdG8gcmVwb3NpdGlvbiBzY3JvbGwgdG8gdGhlIGhhc2hlZCBhbmNob3Igd2hlbiBwYWdlIGxvYWRzLlxuXHRcdHRoaXMubWF5YmVSZXBvc2l0aW9uU2Nyb2xsVG9IYXNoZWRBbmNob3IoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGVzIGJyb3dzZXIgaGlzdG9yeSBjaGFuZ2VzIGFuZCBmaXJlcyBhcHAncyBuYXZpZ2F0aW9uIGlmIHRoZSBzdGF0ZVxuXHQgKiBiZWxvd3MgdG8gdXMuIElmIHdlIGRldGVjdCBhIHBvcHN0YXRlIGFuZCB0aGUgc3RhdGUgaXMgPGNvZGU+bnVsbDwvY29kZT4sXG5cdCAqIGFzc3VtZSBpdCBpcyBuYXZpZ2F0aW5nIHRvIGFuIGV4dGVybmFsIHBhZ2Ugb3IgdG8gYSBwYWdlIHdlIGRvbid0IGhhdmVcblx0ICogcm91dGUsIHRoZW4gPGNvZGU+Z2xvYmFscy53aW5kb3cubG9jYXRpb24ucmVsb2FkKCk8L2NvZGU+IGlzIGludm9rZWQgaW4gb3JkZXIgdG9cblx0ICogcmVsb2FkIHRoZSBjb250ZW50IHRvIHRoZSBjdXJyZW50IHVybC5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IEV2ZW50IGZhY2FkZVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvblBvcHN0YXRlXyhldmVudCkge1xuXHRcdGlmICh0aGlzLnNraXBMb2FkUG9wc3RhdGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEbyBub3QgbmF2aWdhdGUgaWYgdGhlIHBvcHN0YXRlIHdhcyB0cmlnZ2VyZWQgYnkgYSBoYXNoIGNoYW5nZS5cblx0XHRpZiAodXRpbHMuaXNDdXJyZW50QnJvd3NlclBhdGgodGhpcy5icm93c2VyUGF0aEJlZm9yZU5hdmlnYXRlKSkge1xuXHRcdFx0dGhpcy5tYXliZVJlcG9zaXRpb25TY3JvbGxUb0hhc2hlZEFuY2hvcigpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBzdGF0ZSA9IGV2ZW50LnN0YXRlO1xuXG5cdFx0aWYgKCFzdGF0ZSkge1xuXHRcdFx0aWYgKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhhc2gpIHtcblx0XHRcdFx0Ly8gSWYgc2VubmEgaXMgb24gYW4gcmVkaXJlY3QgcGF0aCBhbmQgYSBoYXNoIHBvcHN0YXRlIGhhcHBlbnNcblx0XHRcdFx0Ly8gdG8gYSBkaWZmZXJlbnQgdXJsLCByZWxvYWQgdGhlIGJyb3dzZXIuIFRoaXMgYmVoYXZpb3IgZG9lc24ndFxuXHRcdFx0XHQvLyByZXF1aXJlIHNlbm5hIHRvIHJvdXRlIGhhc2hlZCBsaW5rcyBhbmQgaXMgY2xvc2VyIHRvIG5hdGl2ZVxuXHRcdFx0XHQvLyBicm93c2VyIGJlaGF2aW9yLlxuXHRcdFx0XHRpZiAodGhpcy5yZWRpcmVjdFBhdGggJiYgIXV0aWxzLmlzQ3VycmVudEJyb3dzZXJQYXRoKHRoaXMucmVkaXJlY3RQYXRoKSkge1xuXHRcdFx0XHRcdHRoaXMucmVsb2FkUGFnZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIEFsd2F5cyB0cnkgdG8gcmVwb3NpdGlvbiBzY3JvbGwgdG8gdGhlIGhhc2hlZCBhbmNob3Igd2hlblxuXHRcdFx0XHQvLyBoYXNoIHBvcHN0YXRlIGhhcHBlbnMuXG5cdFx0XHRcdHRoaXMubWF5YmVSZXBvc2l0aW9uU2Nyb2xsVG9IYXNoZWRBbmNob3IoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMucmVsb2FkUGFnZSgpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChzdGF0ZS5zZW5uYSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ0hpc3RvcnkgbmF2aWdhdGlvbiB0byBbJyArIHN0YXRlLnBhdGggKyAnXScpO1xuXHRcdFx0dGhpcy5wb3BzdGF0ZVNjcm9sbFRvcCA9IHN0YXRlLnNjcm9sbFRvcDtcblx0XHRcdHRoaXMucG9wc3RhdGVTY3JvbGxMZWZ0ID0gc3RhdGUuc2Nyb2xsTGVmdDtcblx0XHRcdGlmICghdGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvblN1cHBvcnRlZCkge1xuXHRcdFx0XHR0aGlzLmxvY2tIaXN0b3J5U2Nyb2xsUG9zaXRpb25fKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLm9uY2UoJ2VuZE5hdmlnYXRlJywgKCkgPT4ge1xuXHRcdFx0XHRpZiAoc3RhdGUucmVmZXJyZXIpIHtcblx0XHRcdFx0XHR1dGlscy5zZXRSZWZlcnJlcihzdGF0ZS5yZWZlcnJlcik7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0Y29uc3QgdXJpID0gbmV3IFVyaShzdGF0ZS5wYXRoKTtcblx0XHRcdHVyaS5zZXRIb3N0bmFtZShnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSk7XG5cdFx0XHR1cmkuc2V0UG9ydChnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wb3J0KTtcblx0XHRcdGNvbnN0IGlzTmF2aWdhdGlvblNjaGVkdWxlZCA9IHRoaXMubWF5YmVTY2hlZHVsZU5hdmlnYXRpb25fKHVyaS50b1N0cmluZygpLCB7fSk7XG5cdFx0XHRpZiAoaXNOYXZpZ2F0aW9uU2NoZWR1bGVkKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdHRoaXMubmF2aWdhdGUoc3RhdGUucGF0aCwgdHJ1ZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIExpc3RlbnMgZG9jdW1lbnQgc2Nyb2xsIGNoYW5nZXMgaW4gb3JkZXIgdG8gY2FwdHVyZSB0aGUgcG9zc2libGUgbG9ja1xuXHQgKiBzY3JvbGwgcG9zaXRpb24gZm9yIGhpc3Rvcnkgc2Nyb2xsaW5nLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvblNjcm9sbF8oKSB7XG5cdFx0aWYgKHRoaXMuY2FwdHVyZVNjcm9sbFBvc2l0aW9uRnJvbVNjcm9sbEV2ZW50KSB7XG5cdFx0XHR0aGlzLnNhdmVIaXN0b3J5Q3VycmVudFBhZ2VTY3JvbGxQb3NpdGlvbl8oZ2xvYmFscy53aW5kb3cucGFnZVlPZmZzZXQsIGdsb2JhbHMud2luZG93LnBhZ2VYT2Zmc2V0KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU3RhcnRzIG5hdmlnYXRpb24gdG8gYSBwYXRoLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlIGNvbnRhaW5pbmcgPGNvZGU+cGF0aDwvY29kZT4gYW5kXG5cdCAqICAgICA8Y29kZT5yZXBsYWNlSGlzdG9yeTwvY29kZT4uXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uU3RhcnROYXZpZ2F0ZV8oZXZlbnQpIHtcblx0XHR0aGlzLm1heWJlRGlzYWJsZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uKCk7XG5cdFx0dGhpcy5jYXB0dXJlU2Nyb2xsUG9zaXRpb25Gcm9tU2Nyb2xsRXZlbnQgPSBmYWxzZTtcblx0XHRhZGRDbGFzc2VzKGdsb2JhbHMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCB0aGlzLmxvYWRpbmdDc3NDbGFzcyk7XG5cblx0XHR2YXIgZW5kTmF2aWdhdGVQYXlsb2FkID0ge1xuXHRcdFx0Zm9ybTogZXZlbnQuZm9ybSxcblx0XHRcdHBhdGg6IGV2ZW50LnBhdGhcblx0XHR9O1xuXG5cdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSB0aGlzLmRvTmF2aWdhdGVfKGV2ZW50LnBhdGgsIGV2ZW50LnJlcGxhY2VIaXN0b3J5KVxuXHRcdFx0LmNhdGNoKChyZWFzb24pID0+IHtcblx0XHRcdFx0ZW5kTmF2aWdhdGVQYXlsb2FkLmVycm9yID0gcmVhc29uO1xuXHRcdFx0XHR0aHJvdyByZWFzb247XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW5BbHdheXMoKCkgPT4ge1xuXHRcdFx0XHRpZiAoIXRoaXMucGVuZGluZ05hdmlnYXRlICYmICF0aGlzLnNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZS5sZW5ndGgpIHtcblx0XHRcdFx0XHRyZW1vdmVDbGFzc2VzKGdsb2JhbHMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCB0aGlzLmxvYWRpbmdDc3NDbGFzcyk7XG5cdFx0XHRcdFx0dGhpcy5tYXliZVJlc3RvcmVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbigpO1xuXHRcdFx0XHRcdHRoaXMuY2FwdHVyZVNjcm9sbFBvc2l0aW9uRnJvbVNjcm9sbEV2ZW50ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmVtaXQoJ2VuZE5hdmlnYXRlJywgZW5kTmF2aWdhdGVQYXlsb2FkKTtcblx0XHRcdH0pO1xuXG5cdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUucGF0aCA9IGV2ZW50LnBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogUHJlZmV0Y2hlcyB0aGUgc3BlY2lmaWVkIHBhdGggaWYgdGhlcmUgaXMgYSByb3V0ZSBoYW5kbGVyIHRoYXQgbWF0Y2hlcy5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggdG8gbmF2aWdhdGUgY29udGFpbmluZyB0aGUgYmFzZSBwYXRoLlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IFJldHVybnMgYSBwZW5kaW5nIHJlcXVlc3QgY2FuY2VsbGFibGUgcHJvbWlzZS5cblx0ICovXG5cdHByZWZldGNoKHBhdGgpIHtcblx0XHR2YXIgcm91dGUgPSB0aGlzLmZpbmRSb3V0ZShwYXRoKTtcblx0XHRpZiAoIXJvdXRlKSB7XG5cdFx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yKCdObyByb3V0ZSBmb3IgJyArIHBhdGgpKTtcblx0XHR9XG5cblx0XHRjb25zb2xlLmxvZygnUHJlZmV0Y2hpbmcgWycgKyBwYXRoICsgJ10nKTtcblxuXHRcdHZhciBuZXh0U2NyZWVuID0gdGhpcy5jcmVhdGVTY3JlZW5JbnN0YW5jZShwYXRoLCByb3V0ZSk7XG5cblx0XHRyZXR1cm4gbmV4dFNjcmVlbi5sb2FkKHBhdGgpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLnNjcmVlbnNbcGF0aF0gPSBuZXh0U2NyZWVuKVxuXHRcdFx0LmNhdGNoKChyZWFzb24pID0+IHtcblx0XHRcdFx0dGhpcy5oYW5kbGVOYXZpZ2F0ZUVycm9yXyhwYXRoLCBuZXh0U2NyZWVuLCByZWFzb24pO1xuXHRcdFx0XHR0aHJvdyByZWFzb247XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQcmVwYXJlcyBzY3JlZW4gZmxpcC4gVXBkYXRlcyBoaXN0b3J5IHN0YXRlIGFuZCBzdXJmYWNlcyBjb250ZW50LlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcGFyYW0geyFTY3JlZW59IG5leHRTY3JlZW5cblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JlcGxhY2VIaXN0b3J5IFJlcGxhY2VzIGJyb3dzZXIgaGlzdG9yeS5cblx0ICovXG5cdHByZXBhcmVOYXZpZ2F0ZUhpc3RvcnlfKHBhdGgsIG5leHRTY3JlZW4sIG9wdF9yZXBsYWNlSGlzdG9yeSkge1xuXHRcdGxldCB0aXRsZSA9IG5leHRTY3JlZW4uZ2V0VGl0bGUoKTtcblx0XHRpZiAoIWlzU3RyaW5nKHRpdGxlKSkge1xuXHRcdFx0dGl0bGUgPSB0aGlzLmdldERlZmF1bHRUaXRsZSgpO1xuXHRcdH1cblx0XHRsZXQgcmVkaXJlY3RQYXRoID0gbmV4dFNjcmVlbi5iZWZvcmVVcGRhdGVIaXN0b3J5UGF0aChwYXRoKTtcblx0XHRjb25zdCBoaXN0b3J5U3RhdGUgPSB7XG5cdFx0XHRmb3JtOiBpc0RlZkFuZE5vdE51bGwoZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50KSxcblx0XHRcdHBhdGgsXG5cdFx0XHRyZWRpcmVjdFBhdGgsXG5cdFx0XHRzY3JvbGxMZWZ0OiAwLFxuXHRcdFx0c2Nyb2xsVG9wOiAwLFxuXHRcdFx0c2VubmE6IHRydWVcblx0XHR9O1xuXHRcdGlmIChvcHRfcmVwbGFjZUhpc3RvcnkpIHtcblx0XHRcdGhpc3RvcnlTdGF0ZS5zY3JvbGxUb3AgPSB0aGlzLnBvcHN0YXRlU2Nyb2xsVG9wO1xuXHRcdFx0aGlzdG9yeVN0YXRlLnNjcm9sbExlZnQgPSB0aGlzLnBvcHN0YXRlU2Nyb2xsTGVmdDtcblx0XHR9XG5cdFx0Y29uc3QgaGFzaCA9IG5ldyBVcmkocGF0aCkuZ2V0SGFzaCgpO1xuXHRcdHJlZGlyZWN0UGF0aCA9IHRoaXMubWF5YmVSZXN0b3JlUmVkaXJlY3RQYXRoSGFzaF8ocGF0aCwgcmVkaXJlY3RQYXRoLCBoYXNoKTtcblx0XHR0aGlzLnVwZGF0ZUhpc3RvcnlfKHRpdGxlLCByZWRpcmVjdFBhdGgsIG5leHRTY3JlZW4uYmVmb3JlVXBkYXRlSGlzdG9yeVN0YXRlKGhpc3RvcnlTdGF0ZSksIG9wdF9yZXBsYWNlSGlzdG9yeSk7XG5cdFx0dGhpcy5yZWRpcmVjdFBhdGggPSByZWRpcmVjdFBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogUHJlcGFyZXMgc2NyZWVuIGZsaXAuIFVwZGF0ZXMgaGlzdG9yeSBzdGF0ZSBhbmQgc3VyZmFjZXMgY29udGVudC5cblx0ICogQHBhcmFtIHshU2NyZWVufSBuZXh0U2NyZWVuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gc3VyZmFjZXMgTWFwIG9mIHN1cmZhY2VzIHRvIGZsaXAga2V5ZWQgYnkgc3VyZmFjZSBpZC5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBwYXJhbXMgUGFyYW1zIGV4dHJhY3RlZCBmcm9tIHRoZSBjdXJyZW50IHBhdGguXG5cdCAqL1xuXHRwcmVwYXJlTmF2aWdhdGVTdXJmYWNlc18obmV4dFNjcmVlbiwgc3VyZmFjZXMsIHBhcmFtcykge1xuXHRcdE9iamVjdC5rZXlzKHN1cmZhY2VzKS5mb3JFYWNoKChpZCkgPT4ge1xuXHRcdFx0dmFyIHN1cmZhY2VDb250ZW50ID0gbmV4dFNjcmVlbi5nZXRTdXJmYWNlQ29udGVudChpZCwgcGFyYW1zKTtcblx0XHRcdHN1cmZhY2VzW2lkXS5hZGRDb250ZW50KG5leHRTY3JlZW4uZ2V0SWQoKSwgc3VyZmFjZUNvbnRlbnQpO1xuXHRcdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIG5leHRTY3JlZW4uZ2V0SWQoKSArICddIGFkZCBjb250ZW50IHRvIHN1cmZhY2UgJyArXG5cdFx0XHRcdCdbJyArIHN1cmZhY2VzW2lkXSArICddIFsnICsgKGlzRGVmQW5kTm90TnVsbChzdXJmYWNlQ29udGVudCkgPyAnLi4uJyA6ICdlbXB0eScpICsgJ10nKTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWxvYWRzIHRoZSBwYWdlIGJ5IHBlcmZvcm1pbmcgYHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKWAuXG5cdCAqL1xuXHRyZWxvYWRQYWdlKCkge1xuXHRcdGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgcm91dGUgaW5zdGFuY2UgZnJvbSBhcHAgcm91dGVzLlxuXHQgKiBAcGFyYW0ge1JvdXRlfSByb3V0ZVxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqL1xuXHRyZW1vdmVSb3V0ZShyb3V0ZSkge1xuXHRcdHJldHVybiBhcnJheS5yZW1vdmUodGhpcy5yb3V0ZXMsIHJvdXRlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgc2NyZWVuLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKi9cblx0cmVtb3ZlU2NyZWVuKHBhdGgpIHtcblx0XHR2YXIgc2NyZWVuID0gdGhpcy5zY3JlZW5zW3BhdGhdO1xuXHRcdGlmIChzY3JlZW4pIHtcblx0XHRcdE9iamVjdC5rZXlzKHRoaXMuc3VyZmFjZXMpLmZvckVhY2goKHN1cmZhY2VJZCkgPT4gdGhpcy5zdXJmYWNlc1tzdXJmYWNlSWRdLnJlbW92ZShzY3JlZW4uZ2V0SWQoKSkpO1xuXHRcdFx0c2NyZWVuLmRpc3Bvc2UoKTtcblx0XHRcdGRlbGV0ZSB0aGlzLnNjcmVlbnNbcGF0aF07XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNhdmVzIGdpdmVuIHNjcm9sbCBwb3NpdGlvbiBpbnRvIGhpc3Rvcnkgc3RhdGUuXG5cdCAqIEBwYXJhbSB7IW51bWJlcn0gc2Nyb2xsVG9wIE51bWJlciBjb250YWluaW5nIHRoZSB0b3Agc2Nyb2xsIHBvc2l0aW9uIHRvIGJlIHNhdmVkLlxuXHQgKiBAcGFyYW0geyFudW1iZXJ9IHNjcm9sbExlZnQgTnVtYmVyIGNvbnRhaW5pbmcgdGhlIGxlZnQgc2Nyb2xsIHBvc2l0aW9uIHRvIGJlIHNhdmVkLlxuXHQgKi9cblx0c2F2ZUhpc3RvcnlDdXJyZW50UGFnZVNjcm9sbFBvc2l0aW9uXyhzY3JvbGxUb3AsIHNjcm9sbExlZnQpIHtcblx0XHR2YXIgc3RhdGUgPSBnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnN0YXRlO1xuXHRcdGlmIChzdGF0ZSAmJiBzdGF0ZS5zZW5uYSkge1xuXHRcdFx0W3N0YXRlLnNjcm9sbFRvcCwgc3RhdGUuc2Nyb2xsTGVmdF0gPSBbc2Nyb2xsVG9wLCBzY3JvbGxMZWZ0XTtcblx0XHRcdGdsb2JhbHMud2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHN0YXRlLCBudWxsLCBudWxsKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBhbGxvdyBwcmV2ZW50IG5hdmlnYXRlLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGFsbG93UHJldmVudE5hdmlnYXRlXG5cdCAqL1xuXHRzZXRBbGxvd1ByZXZlbnROYXZpZ2F0ZShhbGxvd1ByZXZlbnROYXZpZ2F0ZSkge1xuXHRcdHRoaXMuYWxsb3dQcmV2ZW50TmF2aWdhdGUgPSBhbGxvd1ByZXZlbnROYXZpZ2F0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIGxpbmsgYmFzZSBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGhcblx0ICovXG5cdHNldEJhc2VQYXRoKGJhc2VQYXRoKSB7XG5cdFx0dGhpcy5iYXNlUGF0aCA9IHV0aWxzLnJlbW92ZVBhdGhUcmFpbGluZ1NsYXNoKGJhc2VQYXRoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBkZWZhdWx0IHBhZ2UgdGl0bGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBkZWZhdWx0VGl0bGVcblx0ICovXG5cdHNldERlZmF1bHRUaXRsZShkZWZhdWx0VGl0bGUpIHtcblx0XHR0aGlzLmRlZmF1bHRUaXRsZSA9IGRlZmF1bHRUaXRsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBmb3JtIHNlbGVjdG9yLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGZvcm1TZWxlY3RvclxuXHQgKi9cblx0c2V0Rm9ybVNlbGVjdG9yKGZvcm1TZWxlY3Rvcikge1xuXHRcdHRoaXMuZm9ybVNlbGVjdG9yID0gZm9ybVNlbGVjdG9yO1xuXHRcdGlmICh0aGlzLmZvcm1FdmVudEhhbmRsZXJfKSB7XG5cdFx0XHR0aGlzLmZvcm1FdmVudEhhbmRsZXJfLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0fVxuXHRcdHRoaXMuZm9ybUV2ZW50SGFuZGxlcl8gPSBkZWxlZ2F0ZShkb2N1bWVudCwgJ3N1Ym1pdCcsIHRoaXMuZm9ybVNlbGVjdG9yLCB0aGlzLm9uRG9jU3VibWl0RGVsZWdhdGVfLmJpbmQodGhpcyksIHRoaXMuYWxsb3dQcmV2ZW50TmF2aWdhdGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgaWYgcm91dGUgbWF0Y2hpbmcgc2hvdWxkIGlnbm9yZSBxdWVyeSBzdHJpbmcgZnJvbSB0aGUgcm91dGUgcGF0aC5cblx0ICogQHBhcmFtIHtib29sZWFufSBpZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGhcblx0ICovXG5cdHNldElnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aChpZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGgpIHtcblx0XHR0aGlzLmlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCA9IGlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBsaW5rIHNlbGVjdG9yLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGxpbmtTZWxlY3RvclxuXHQgKi9cblx0c2V0TGlua1NlbGVjdG9yKGxpbmtTZWxlY3Rvcikge1xuXHRcdHRoaXMubGlua1NlbGVjdG9yID0gbGlua1NlbGVjdG9yO1xuXHRcdGlmICh0aGlzLmxpbmtFdmVudEhhbmRsZXJfKSB7XG5cdFx0XHR0aGlzLmxpbmtFdmVudEhhbmRsZXJfLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0fVxuXHRcdHRoaXMubGlua0V2ZW50SGFuZGxlcl8gPSBkZWxlZ2F0ZShkb2N1bWVudCwgJ2NsaWNrJywgdGhpcy5saW5rU2VsZWN0b3IsIHRoaXMub25Eb2NDbGlja0RlbGVnYXRlXy5iaW5kKHRoaXMpLCB0aGlzLmFsbG93UHJldmVudE5hdmlnYXRlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBsb2FkaW5nIGNzcyBjbGFzcy5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBsb2FkaW5nQ3NzQ2xhc3Ncblx0ICovXG5cdHNldExvYWRpbmdDc3NDbGFzcyhsb2FkaW5nQ3NzQ2xhc3MpIHtcblx0XHR0aGlzLmxvYWRpbmdDc3NDbGFzcyA9IGxvYWRpbmdDc3NDbGFzcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSB1cGRhdGUgc2Nyb2xsIHBvc2l0aW9uIHZhbHVlLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHVwZGF0ZVNjcm9sbFBvc2l0aW9uXG5cdCAqL1xuXHRzZXRVcGRhdGVTY3JvbGxQb3NpdGlvbih1cGRhdGVTY3JvbGxQb3NpdGlvbikge1xuXHRcdHRoaXMudXBkYXRlU2Nyb2xsUG9zaXRpb24gPSB1cGRhdGVTY3JvbGxQb3NpdGlvbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYW5jZWxzIHBlbmRpbmcgbmF2aWdhdGUgd2l0aCA8Y29kZT5DYW5jZWwgcGVuZGluZyBuYXZpZ2F0aW9uPC9jb2RlPiBlcnJvci5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0c3RvcFBlbmRpbmdOYXZpZ2F0ZV8oKSB7XG5cdFx0aWYgKHRoaXMucGVuZGluZ05hdmlnYXRlKSB7XG5cdFx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZS5jYW5jZWwoJ0NhbmNlbCBwZW5kaW5nIG5hdmlnYXRpb24nKTtcblx0XHR9XG5cdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFN5bmMgZG9jdW1lbnQgc2Nyb2xsIHBvc2l0aW9uIHR3aWNlLCB0aGUgZmlyc3Qgb25lIHN5bmNocm9ub3VzIGFuZCB0aGVuXG5cdCAqIG9uZSBpbnNpZGUgPGNvZGU+YXN5bmMubmV4dFRpY2s8L2NvZGU+LiBSZWxldmFudCB0byBicm93c2VycyB0aGF0IGZpcmVzXG5cdCAqIHNjcm9sbCByZXN0b3JhdGlvbiBhc3luY2hyb25vdXNseSBhZnRlciBwb3BzdGF0ZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKiBAcmV0dXJuIHs/Q2FuY2VsbGFibGVQcm9taXNlPX1cblx0ICovXG5cdHN5bmNTY3JvbGxQb3NpdGlvblN5bmNUaGVuQXN5bmNfKCkge1xuXHRcdHZhciBzdGF0ZSA9IGdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc3RhdGU7XG5cdFx0aWYgKCFzdGF0ZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBzY3JvbGxUb3AgPSBzdGF0ZS5zY3JvbGxUb3A7XG5cdFx0dmFyIHNjcm9sbExlZnQgPSBzdGF0ZS5zY3JvbGxMZWZ0O1xuXG5cdFx0dmFyIHN5bmMgPSAoKSA9PiB7XG5cdFx0XHRpZiAodGhpcy51cGRhdGVTY3JvbGxQb3NpdGlvbikge1xuXHRcdFx0XHRnbG9iYWxzLndpbmRvdy5zY3JvbGxUbyhzY3JvbGxMZWZ0LCBzY3JvbGxUb3ApO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSkgPT4gc3luYygpICYgYXN5bmMubmV4dFRpY2soKCkgPT4gc3luYygpICYgcmVzb2x2ZSgpKSk7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyBvciByZXBsYWNlIGJyb3dzZXIgaGlzdG9yeS5cblx0ICogQHBhcmFtIHs/c3RyaW5nfSB0aXRsZSBEb2N1bWVudCB0aXRsZS5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHBhcmFtIHshb2JqZWN0fSBzdGF0ZVxuXHQgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmVwbGFjZUhpc3RvcnkgUmVwbGFjZXMgYnJvd3NlciBoaXN0b3J5LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR1cGRhdGVIaXN0b3J5Xyh0aXRsZSwgcGF0aCwgc3RhdGUsIG9wdF9yZXBsYWNlSGlzdG9yeSkge1xuXHRcdGNvbnN0IHJlZmVycmVyID0gZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaHJlZjtcblxuXHRcdGlmIChzdGF0ZSkge1xuXHRcdFx0c3RhdGUucmVmZXJyZXIgPSByZWZlcnJlcjtcblx0XHR9XG5cblx0XHRpZiAob3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0XHRnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShzdGF0ZSwgdGl0bGUsIHBhdGgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZShzdGF0ZSwgdGl0bGUsIHBhdGgpO1xuXHRcdH1cblxuXHRcdHV0aWxzLnNldFJlZmVycmVyKHJlZmVycmVyKTtcblxuXHRcdGxldCB0aXRsZU5vZGUgPSBnbG9iYWxzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3RpdGxlJyk7XG5cdFx0aWYgKHRpdGxlTm9kZSkge1xuXHRcdFx0dGl0bGVOb2RlLmlubmVySFRNTCA9IHRpdGxlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRnbG9iYWxzLmRvY3VtZW50LnRpdGxlID0gdGl0bGU7XG5cdFx0fVxuXHR9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0RlZiwgaXNEZWZBbmROb3ROdWxsIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuaW1wb3J0IHsgQ2FuY2VsbGFibGVQcm9taXNlIGFzIFByb21pc2UgfSBmcm9tICdtZXRhbC1wcm9taXNlJztcblxuY2xhc3MgQWpheCB7XG5cblx0LyoqXG5cdCAqIFhtbEh0dHBSZXF1ZXN0J3MgZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkgbWV0aG9kIHJldHVybnMgYSBzdHJpbmcgb2Zcblx0ICogcmVzcG9uc2UgaGVhZGVycyBhY2NvcmRpbmcgdG8gdGhlIGZvcm1hdCBkZXNjcmliZWQgb24gdGhlIHNwZWM6XG5cdCAqIHtAbGluayBodHRwOi8vd3d3LnczLm9yZy9UUi9YTUxIdHRwUmVxdWVzdC8jdGhlLWdldGFsbHJlc3BvbnNlaGVhZGVycy1tZXRob2R9LlxuXHQgKiBUaGlzIG1ldGhvZCBwYXJzZXMgdGhhdCBzdHJpbmcgaW50byBhIHVzZXItZnJpZW5kbHkgbmFtZS92YWx1ZSBwYWlyXG5cdCAqIG9iamVjdC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGFsbEhlYWRlcnMgQWxsIGhlYWRlcnMgYXMgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHshQXJyYXkuPE9iamVjdDxzdHJpbmcsIHN0cmluZz4+fVxuXHQgKi9cblx0c3RhdGljIHBhcnNlUmVzcG9uc2VIZWFkZXJzKGFsbEhlYWRlcnMpIHtcblx0XHR2YXIgaGVhZGVycyA9IFtdO1xuXHRcdGlmICghYWxsSGVhZGVycykge1xuXHRcdFx0cmV0dXJuIGhlYWRlcnM7XG5cdFx0fVxuXHRcdHZhciBwYWlycyA9IGFsbEhlYWRlcnMuc3BsaXQoJ1xcdTAwMGRcXHUwMDBhJyk7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBwYWlycy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGluZGV4ID0gcGFpcnNbaV0uaW5kZXhPZignXFx1MDAzYVxcdTAwMjAnKTtcblx0XHRcdGlmIChpbmRleCA+IDApIHtcblx0XHRcdFx0dmFyIG5hbWUgPSBwYWlyc1tpXS5zdWJzdHJpbmcoMCwgaW5kZXgpO1xuXHRcdFx0XHR2YXIgdmFsdWUgPSBwYWlyc1tpXS5zdWJzdHJpbmcoaW5kZXggKyAyKTtcblx0XHRcdFx0aGVhZGVycy5wdXNoKHtcblx0XHRcdFx0XHRuYW1lOiBuYW1lLFxuXHRcdFx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGhlYWRlcnM7XG5cdH1cblxuXHQvKipcblx0ICogUmVxdWVzdHMgdGhlIHVybCB1c2luZyBYTUxIdHRwUmVxdWVzdC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSB1cmxcblx0ICogQHBhcmFtIHshc3RyaW5nfSBtZXRob2Rcblx0ICogQHBhcmFtIHs/c3RyaW5nfSBib2R5XG5cdCAqIEBwYXJhbSB7TXVsdGlNYXA9fSBvcHRfaGVhZGVyc1xuXHQgKiBAcGFyYW0ge011bHRpTWFwPX0gb3B0X3BhcmFtc1xuXHQgKiBAcGFyYW0ge251bWJlcj19IG9wdF90aW1lb3V0XG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zeW5jXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF93aXRoQ3JlZGVudGlhbHNcblx0ICogQHJldHVybiB7UHJvbWlzZX0gRGVmZXJyZWQgYWpheCByZXF1ZXN0LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzdGF0aWMgcmVxdWVzdCh1cmwsIG1ldGhvZCwgYm9keSwgb3B0X2hlYWRlcnMsIG9wdF9wYXJhbXMsIG9wdF90aW1lb3V0LCBvcHRfc3luYywgb3B0X3dpdGhDcmVkZW50aWFscykge1xuXHRcdHVybCA9IHVybCB8fCAnJztcblx0XHRtZXRob2QgPSBtZXRob2QgfHwgJ0dFVCc7XG5cblx0XHR2YXIgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXHRcdHZhciBwcmV2aW91c1JlYWR5U3RhdGUgPSAwO1xuXG5cdFx0dmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblx0XHRcdHJlcXVlc3Qub25sb2FkID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmIChyZXF1ZXN0LmFib3J0ZWQpIHtcblx0XHRcdFx0XHRyZXF1ZXN0Lm9uZXJyb3IoKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0cmVzb2x2ZShyZXF1ZXN0KTtcblx0XHRcdH07XG5cdFx0XHRyZXF1ZXN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAocHJldmlvdXNSZWFkeVN0YXRlICYmIHByZXZpb3VzUmVhZHlTdGF0ZSA8IDMgJiYgNCA9PT0gcmVxdWVzdC5yZWFkeVN0YXRlKSB7XG5cdFx0XHRcdFx0cmVxdWVzdC50ZXJtaW5hdGVkUHJlbWF0dXJlbHkgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHByZXZpb3VzUmVhZHlTdGF0ZSA9IHJlcXVlc3QucmVhZHlTdGF0ZTtcblx0XHRcdH07XG5cdFx0XHRyZXF1ZXN0Lm9uZXJyb3IgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIG1lc3NhZ2UgPSAnUmVxdWVzdCBlcnJvcic7XG5cdFx0XHRcdGlmIChyZXF1ZXN0LnRlcm1pbmF0ZWRQcmVtYXR1cmVseSkge1xuXHRcdFx0XHRcdG1lc3NhZ2UgPSAnUmVxdWVzdCB0ZXJtaW5hdGVkIHByZW1hdHVyZWx5Jztcblx0XHRcdFx0fSBcblx0XHRcdFx0dmFyIGVycm9yID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xuXHRcdFx0XHRlcnJvci5yZXF1ZXN0ID0gcmVxdWVzdDtcblx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdH07XG5cdFx0fSkudGhlbkNhdGNoKGZ1bmN0aW9uKHJlYXNvbikge1xuXHRcdFx0cmVxdWVzdC5hYm9ydCgpO1xuXHRcdFx0dGhyb3cgcmVhc29uO1xuXHRcdH0pLnRoZW5BbHdheXMoZnVuY3Rpb24oKSB7XG5cdFx0XHRjbGVhclRpbWVvdXQodGltZW91dCk7XG5cdFx0fSk7XG5cblx0XHR1cmwgPSBuZXcgVXJpKHVybCk7XG5cblx0XHRpZiAob3B0X3BhcmFtcykge1xuXHRcdFx0dXJsLmFkZFBhcmFtZXRlcnNGcm9tTXVsdGlNYXAob3B0X3BhcmFtcykudG9TdHJpbmcoKTtcblx0XHR9XG5cblx0XHR1cmwgPSB1cmwudG9TdHJpbmcoKTtcblxuXHRcdHJlcXVlc3Qub3BlbihtZXRob2QsIHVybCwgIW9wdF9zeW5jKTtcblxuXHRcdGlmIChvcHRfd2l0aENyZWRlbnRpYWxzKSB7XG5cdFx0XHRyZXF1ZXN0LndpdGhDcmVkZW50aWFscyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKG9wdF9oZWFkZXJzKSB7XG5cdFx0XHRvcHRfaGVhZGVycy5uYW1lcygpLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuXHRcdFx0XHRyZXF1ZXN0LnNldFJlcXVlc3RIZWFkZXIobmFtZSwgb3B0X2hlYWRlcnMuZ2V0QWxsKG5hbWUpLmpvaW4oJywgJykpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmVxdWVzdC5zZW5kKGlzRGVmKGJvZHkpID8gYm9keSA6IG51bGwpO1xuXG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChvcHRfdGltZW91dCkpIHtcblx0XHRcdHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdFx0cHJvbWlzZS5jYW5jZWwoJ1JlcXVlc3QgdGltZW91dCcpO1xuXHRcdFx0fSwgb3B0X3RpbWVvdXQpO1xuXHRcdH1cblxuXHRcdHJldHVybiBwcm9taXNlO1xuXHR9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgQWpheDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBIb2xkcyB2YWx1ZSBlcnJvciBtZXNzYWdlcy5cbiAqIEBjb25zdFxuICovXG5jbGFzcyBlcnJvcnMge1xufVxuXG4vKipcbiAqIEludmFsaWQgc3RhdHVzIGVycm9yIG1lc3NhZ2UuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQHN0YXRpY1xuICovXG5lcnJvcnMuSU5WQUxJRF9TVEFUVVMgPSAnSW52YWxpZCBzdGF0dXMgY29kZSc7XG5cbi8qKlxuICogUmVxdWVzdCBlcnJvciBtZXNzYWdlLlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuZXJyb3JzLlJFUVVFU1RfRVJST1IgPSAnUmVxdWVzdCBlcnJvcic7XG5cbi8qKlxuICogUmVxdWVzdCB0aW1lb3V0IGVycm9yIG1lc3NhZ2UuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQHN0YXRpY1xuICovXG5lcnJvcnMuUkVRVUVTVF9USU1FT1VUID0gJ1JlcXVlc3QgdGltZW91dCc7XG5cbi8qKlxuICogUmVxdWVzdCBpcyBibG9ja2VkIGJ5IENPUlMgaXNzdWUgbWVzc2FnZS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cbmVycm9ycy5SRVFVRVNUX1BSRU1BVFVSRV9URVJNSU5BVElPTiA9ICdSZXF1ZXN0IHRlcm1pbmF0ZWQgcHJlbWF0dXJlbHknO1xuXG5leHBvcnQgZGVmYXVsdCBlcnJvcnM7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7aXNTZXJ2ZXJTaWRlfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogTWV0YWwuanMgYnJvd3NlciB1c2VyIGFnZW50IGRldGVjdGlvbi4gSXQncyBleHRyZW1lbHkgcmVjb21tZW5kZWQgdGhlIHVzYWdlXG4gKiBvZiBmZWF0dXJlIGNoZWNraW5nIG92ZXIgYnJvd3NlciB1c2VyIGFnZW50IHNuaWZmaW5nLiBVbmZvcnR1bmF0ZWx5LCBpbiBzb21lXG4gKiBzaXR1YXRpb25zIGZlYXR1cmUgY2hlY2tpbmcgY2FuIGJlIHNsb3cgb3IgZXZlbiBpbXBvc3NpYmxlLCB0aGVyZWZvcmUgdXNlXG4gKiB0aGlzIHV0aWxpdHkgd2l0aCBjYXV0aW9uLlxuICogQHNlZSA8YSBocmVmPVwiaHR0cDovL3d3dy51c2VyYWdlbnRzdHJpbmcuY29tL1wiPlVzZXIgYWdlbnQgc3RyaW5nczwvYT4uXG4gKi9cbmNsYXNzIFVBIHtcblx0LyoqXG5cdCAqIEdldHMgdGhlIG5hdGl2ZSB1c2VyQWdlbnQgc3RyaW5nIGZyb20gbmF2aWdhdG9yIGlmIGl0IGV4aXN0cy4gSWZcblx0ICogbmF2aWdhdG9yIG9yIG5hdmlnYXRvci51c2VyQWdlbnQgc3RyaW5nIGlzIG1pc3NpbmcsIHJldHVybnMgYW4gZW1wdHlcblx0ICogc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXROYXRpdmVVc2VyQWdlbnQoKSB7XG5cdFx0bGV0IG5hdmlnYXRvciA9IFVBLmdsb2JhbHMud2luZG93ICYmIFVBLmdsb2JhbHMud2luZG93Lm5hdmlnYXRvcjtcblx0XHRpZiAobmF2aWdhdG9yKSB7XG5cdFx0XHRsZXQgdXNlckFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudDtcblx0XHRcdGlmICh1c2VyQWdlbnQpIHtcblx0XHRcdFx0cmV0dXJuIHVzZXJBZ2VudDtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIG5hdGl2ZSBwbGF0Zm9ybSBzdHJpbmcgZnJvbSBuYXZpZ2F0b3IgaWYgaXQgZXhpc3RzLiBJZlxuXHQgKiBuYXZpZ2F0b3Igb3IgbmF2aWdhdG9yLnBsYXRmb3JtIHN0cmluZyBpcyBtaXNzaW5nLCByZXR1cm5zIGFuIGVtcHR5XG5cdCAqIHN0cmluZy5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0TmF0aXZlUGxhdGZvcm0oKSB7XG5cdFx0bGV0IG5hdmlnYXRvciA9IFVBLmdsb2JhbHMud2luZG93ICYmIFVBLmdsb2JhbHMud2luZG93Lm5hdmlnYXRvcjtcblx0XHRpZiAobmF2aWdhdG9yKSB7XG5cdFx0XHRsZXQgcGxhdGZvcm0gPSBuYXZpZ2F0b3IucGxhdGZvcm07XG5cdFx0XHRpZiAocGxhdGZvcm0pIHtcblx0XHRcdFx0cmV0dXJuIHBsYXRmb3JtO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gJyc7XG5cdH1cblxuXHQvKipcblx0ICogV2hldGhlciB0aGUgcGxhdGZvcm0gY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZywgaWdub3JpbmcgY2FzZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0clxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgbWF0Y2hQbGF0Zm9ybShzdHIpIHtcblx0XHRyZXR1cm4gVUEucGxhdGZvcm0uaW5kZXhPZihzdHIpICE9PSAtMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBXaGV0aGVyIHRoZSB1c2VyIGFnZW50IGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcsIGlnbm9yaW5nIGNhc2UuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByaXZhdGVcblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIG1hdGNoVXNlckFnZW50KHN0cikge1xuXHRcdHJldHVybiBVQS51c2VyQWdlbnQuaW5kZXhPZihzdHIpICE9PSAtMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUZXN0cyB0aGUgdXNlciBhZ2VudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHVzZXJBZ2VudCBUaGUgdXNlciBhZ2VudCBzdHJpbmcuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwbGF0Zm9ybVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgdGVzdFVzZXJBZ2VudCh1c2VyQWdlbnQgPSAnJywgcGxhdGZvcm0gPSAnJykge1xuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSB1c2VyIGFnZW50IHZhbHVlIGV4dHJhY3RlZCBmcm9tIGJyb3dzZXIgbmF0aXZlIHVzZXIgYWdlbnQuXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEudXNlckFnZW50ID0gdXNlckFnZW50O1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHBsYXRmb3JtIHZhbHVlIGV4dHJhY3RlZCBmcm9tIGJyb3dzZXIgbmF0aXZlIHBsYXRmb3JtLlxuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLnBsYXRmb3JtID0gcGxhdGZvcm07XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgT1MgaXMgTWFjLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc01hYyA9IFVBLm1hdGNoUGxhdGZvcm0oJ01hYycpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIE9TIGlzIFdpbi5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNXaW4gPSBVQS5tYXRjaFBsYXRmb3JtKCdXaW4nKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIE9wZXJhLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc09wZXJhID0gVUEubWF0Y2hVc2VyQWdlbnQoJ09wZXJhJykgfHwgVUEubWF0Y2hVc2VyQWdlbnQoJ09QUicpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgSUUuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzSWUgPSBVQS5tYXRjaFVzZXJBZ2VudCgnVHJpZGVudCcpIHx8IFVBLm1hdGNoVXNlckFnZW50KCdNU0lFJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBFZGdlLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc0VkZ2UgPSBVQS5tYXRjaFVzZXJBZ2VudCgnRWRnZScpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgSUUgb3IgRWRnZS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNJZU9yRWRnZSA9IFVBLmlzSWUgfHwgVUEuaXNFZGdlO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgQ2hyb21lLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc0Nocm9tZSA9XG5cdFx0XHQoVUEubWF0Y2hVc2VyQWdlbnQoJ0Nocm9tZScpIHx8IFVBLm1hdGNoVXNlckFnZW50KCdDcmlPUycpKSAmJlxuXHRcdFx0IVVBLmlzT3BlcmEgJiZcblx0XHRcdCFVQS5pc0VkZ2U7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBTYWZhcmkuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzU2FmYXJpID1cblx0XHRcdFVBLm1hdGNoVXNlckFnZW50KCdTYWZhcmknKSAmJlxuXHRcdFx0IShVQS5pc0Nocm9tZSB8fCBVQS5pc09wZXJhIHx8IFVBLmlzRWRnZSk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBGaXJlZm94LlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc0ZpcmVmb3ggPSBVQS5tYXRjaFVzZXJBZ2VudCgnRmlyZWZveCcpO1xuXHR9XG59XG5cbi8qKlxuICogRXhwb3NlcyBnbG9iYWwgcmVmZXJlbmNlcy5cbiAqIEB0eXBlIHtvYmplY3R9XG4gKiBAc3RhdGljXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShVQSwgJ2dsb2JhbHMnLCB7XG5cdHdyaXRhYmxlOiB0cnVlLFxuXHR2YWx1ZToge1xuXHRcdHdpbmRvdzogaXNTZXJ2ZXJTaWRlKCkgPyBudWxsIDogd2luZG93LFxuXHR9LFxufSk7XG5cblVBLnRlc3RVc2VyQWdlbnQoVUEuZ2V0TmF0aXZlVXNlckFnZW50KCksIFVBLmdldE5hdGl2ZVBsYXRmb3JtKCkpO1xuXG5leHBvcnQgZGVmYXVsdCBVQTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgaXNEZWZBbmROb3ROdWxsIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IEFqYXggZnJvbSAnbWV0YWwtYWpheCc7XG5pbXBvcnQgeyBNdWx0aU1hcCB9IGZyb20gJ21ldGFsLXN0cnVjdHMnO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcbmltcG9ydCBlcnJvcnMgZnJvbSAnLi4vZXJyb3JzL2Vycm9ycyc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi4vdXRpbHMvdXRpbHMnO1xuaW1wb3J0IGdsb2JhbHMgZnJvbSAnLi4vZ2xvYmFscy9nbG9iYWxzJztcbmltcG9ydCBTY3JlZW4gZnJvbSAnLi9TY3JlZW4nO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuaW1wb3J0IFVBIGZyb20gJ21ldGFsLXVzZXJhZ2VudCc7XG5cbmNsYXNzIFJlcXVlc3RTY3JlZW4gZXh0ZW5kcyBTY3JlZW4ge1xuXG5cdC8qKlxuXHQgKiBSZXF1ZXN0IHNjcmVlbiBhYnN0cmFjdCBjbGFzcyB0byBwZXJmb3JtIGlvIG9wZXJhdGlvbnMgb24gZGVzY2VuZGFudFxuXHQgKiBzY3JlZW5zLlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQGV4dGVuZHMge1NjcmVlbn1cblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBAaW5oZXJpdERvY1xuXHRcdCAqIEBkZWZhdWx0IHRydWVcblx0XHQgKi9cblx0XHR0aGlzLmNhY2hlYWJsZSA9IHRydWU7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBkZWZhdWx0IGh0dHAgaGVhZGVycyB0byBzZXQgb24gcmVxdWVzdC5cblx0XHQgKiBAdHlwZSB7P09iamVjdD19XG5cdFx0ICogQGRlZmF1bHQge1xuXHRcdCAqICAgJ1gtUEpBWCc6ICd0cnVlJyxcblx0XHQgKiAgICdYLVJlcXVlc3RlZC1XaXRoJzogJ1hNTEh0dHBSZXF1ZXN0J1xuXHRcdCAqIH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5odHRwSGVhZGVycyA9IHtcblx0XHRcdCdYLVBKQVgnOiAndHJ1ZScsXG5cdFx0XHQnWC1SZXF1ZXN0ZWQtV2l0aCc6ICdYTUxIdHRwUmVxdWVzdCdcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgZGVmYXVsdCBodHRwIG1ldGhvZCB0byBwZXJmb3JtIHRoZSByZXF1ZXN0LlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IFJlcXVlc3RTY3JlZW4uR0VUXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaHR0cE1ldGhvZCA9IFJlcXVlc3RTY3JlZW4uR0VUO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIFhIUiBvYmplY3QgcmVzcG9uc2libGUgZm9yIHRoZSByZXF1ZXN0LlxuXHRcdCAqIEB0eXBlIHtYTUxIdHRwUmVxdWVzdH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucmVxdWVzdCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgcmVxdWVzdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cblx0XHQgKiBAdHlwZSB7IW51bWJlcn1cblx0XHQgKiBAZGVmYXVsdCAzMDAwMFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnRpbWVvdXQgPSAzMDAwMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBBc3NlcnRzIHRoYXQgcmVzcG9uc2Ugc3RhdHVzIGNvZGUgaXMgdmFsaWQuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGF0dXNcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YXNzZXJ0VmFsaWRSZXNwb25zZVN0YXR1c0NvZGUoc3RhdHVzKSB7XG5cdFx0aWYgKCF0aGlzLmlzVmFsaWRSZXNwb25zZVN0YXR1c0NvZGUoc3RhdHVzKSkge1xuXHRcdFx0dmFyIGVycm9yID0gbmV3IEVycm9yKGVycm9ycy5JTlZBTElEX1NUQVRVUyk7XG5cdFx0XHRlcnJvci5pbnZhbGlkU3RhdHVzID0gdHJ1ZTtcblx0XHRcdGVycm9yLnN0YXR1c0NvZGUgPSBzdGF0dXM7XG5cdFx0XHR0aHJvdyBlcnJvcjtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGJlZm9yZVVwZGF0ZUhpc3RvcnlQYXRoKHBhdGgpIHtcblx0XHR2YXIgcmVkaXJlY3RQYXRoID0gdGhpcy5nZXRSZXF1ZXN0UGF0aCgpO1xuXHRcdGlmIChyZWRpcmVjdFBhdGggJiYgcmVkaXJlY3RQYXRoICE9PSBwYXRoKSB7XG5cdFx0XHRyZXR1cm4gcmVkaXJlY3RQYXRoO1xuXHRcdH1cblx0XHRyZXR1cm4gcGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0YmVmb3JlVXBkYXRlSGlzdG9yeVN0YXRlKHN0YXRlKSB7XG5cdFx0Ly8gSWYgc3RhdGUgaXMgb3VycyBhbmQgbmF2aWdhdGUgdG8gcG9zdC13aXRob3V0LXJlZGlyZWN0LWdldCBzZXRcblx0XHQvLyBoaXN0b3J5IHN0YXRlIHRvIG51bGwsIHRoYXQgd2F5IFNlbm5hIHdpbGwgcmVsb2FkIHRoZSBwYWdlIG9uXG5cdFx0Ly8gcG9wc3RhdGUgc2luY2UgaXQgY2Fubm90IHByZWRpY3QgcG9zdCBkYXRhLlxuXHRcdGlmIChzdGF0ZS5zZW5uYSAmJiBzdGF0ZS5mb3JtICYmIHN0YXRlLnJlZGlyZWN0UGF0aCA9PT0gc3RhdGUucGF0aCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXHRcdHJldHVybiBzdGF0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGb3JtYXRzIGxvYWQgcGF0aCBiZWZvcmUgaW52b2tpbmcgYWpheCBjYWxsLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEZvcm1hdHRlZCBwYXRoO1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRmb3JtYXRMb2FkUGF0aChwYXRoKSB7XG5cdFx0dmFyIHVyaSA9IG5ldyBVcmkocGF0aCk7XG5cblx0XHR1cmkuc2V0SG9zdG5hbWUoZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaG9zdG5hbWUpO1xuXHRcdHVyaS5zZXRQcm90b2NvbChnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCk7XG5cblx0XHRpZiAoZ2xvYmFscy53aW5kb3cubG9jYXRpb24ucG9ydCkge1xuXHRcdFx0dXJpLnNldFBvcnQoZ2xvYmFscy53aW5kb3cubG9jYXRpb24ucG9ydCk7XG5cdFx0fVxuXG5cdFx0aWYgKFVBLmlzSWVPckVkZ2UgJiYgdGhpcy5odHRwTWV0aG9kID09PSBSZXF1ZXN0U2NyZWVuLkdFVCkge1xuXHRcdFx0cmV0dXJuIHVyaS5tYWtlVW5pcXVlKCkudG9TdHJpbmcoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdXJpLnRvU3RyaW5nKCk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgaHR0cCBoZWFkZXJzLlxuXHQgKiBAcmV0dXJuIHs/T2JqZWN0PX1cblx0ICovXG5cdGdldEh0dHBIZWFkZXJzKCkge1xuXHRcdHJldHVybiB0aGlzLmh0dHBIZWFkZXJzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGh0dHAgbWV0aG9kLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0SHR0cE1ldGhvZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5odHRwTWV0aG9kO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgcmVxdWVzdCBwYXRoLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmc9fVxuXHQgKi9cblx0Z2V0UmVxdWVzdFBhdGgoKSB7XG5cdFx0dmFyIHJlcXVlc3QgPSB0aGlzLmdldFJlcXVlc3QoKTtcblx0XHRpZiAocmVxdWVzdCkge1xuXHRcdFx0dmFyIHJlcXVlc3RQYXRoID0gcmVxdWVzdC5yZXF1ZXN0UGF0aDtcblx0XHRcdHZhciByZXNwb25zZVVybCA9IHRoaXMubWF5YmVFeHRyYWN0UmVzcG9uc2VVcmxGcm9tUmVxdWVzdChyZXF1ZXN0KTtcblx0XHRcdGlmIChyZXNwb25zZVVybCkge1xuXHRcdFx0XHRyZXF1ZXN0UGF0aCA9IHJlc3BvbnNlVXJsO1xuXHRcdFx0fVxuXHRcdFx0aWYgKFVBLmlzSWVPckVkZ2UgJiYgdGhpcy5odHRwTWV0aG9kID09PSBSZXF1ZXN0U2NyZWVuLkdFVCkge1xuXHRcdFx0XHRyZXF1ZXN0UGF0aCA9IG5ldyBVcmkocmVxdWVzdFBhdGgpLnJlbW92ZVVuaXF1ZSgpLnRvU3RyaW5nKCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdXRpbHMuZ2V0VXJsUGF0aChyZXF1ZXN0UGF0aCk7XG5cdFx0fVxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHJlcXVlc3Qgb2JqZWN0LlxuXHQgKiBAcmV0dXJuIHs/T2JqZWN0fVxuXHQgKi9cblx0Z2V0UmVxdWVzdCgpIHtcblx0XHRyZXR1cm4gdGhpcy5yZXF1ZXN0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHJlcXVlc3QgdGltZW91dC5cblx0ICogQHJldHVybiB7IW51bWJlcn1cblx0ICovXG5cdGdldFRpbWVvdXQoKSB7XG5cdFx0cmV0dXJuIHRoaXMudGltZW91dDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgcmVzcG9uc2Ugc3VjY2VlZGVkLiBBbnkgc3RhdHVzIGNvZGUgMnh4IG9yIDN4eCBpcyBjb25zaWRlcmVkXG5cdCAqIHZhbGlkLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gc3RhdHVzQ29kZVxuXHQgKi9cblx0aXNWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZShzdGF0dXNDb2RlKSB7XG5cdFx0cmV0dXJuIHN0YXR1c0NvZGUgPj0gMjAwICYmIHN0YXR1c0NvZGUgPD0gMzk5O1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRsb2FkKHBhdGgpIHtcblx0XHRjb25zdCBjYWNoZSA9IHRoaXMuZ2V0Q2FjaGUoKTtcblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKGNhY2hlKSkge1xuXHRcdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKGNhY2hlKTtcblx0XHR9XG5cdFx0bGV0IGJvZHkgPSBudWxsO1xuXHRcdGxldCBodHRwTWV0aG9kID0gdGhpcy5odHRwTWV0aG9kO1xuXHRcdGNvbnN0IGhlYWRlcnMgPSBuZXcgTXVsdGlNYXAoKTtcblx0XHRPYmplY3Qua2V5cyh0aGlzLmh0dHBIZWFkZXJzKS5mb3JFYWNoKGhlYWRlciA9PiBoZWFkZXJzLmFkZChoZWFkZXIsIHRoaXMuaHR0cEhlYWRlcnNbaGVhZGVyXSkpO1xuXHRcdGlmIChnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQpIHtcblx0XHRcdHRoaXMuYWRkU2FmYXJpWEhSUG9seWZpbGwoKTtcblx0XHRcdGJvZHkgPSBuZXcgRm9ybURhdGEoZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50KTtcblx0XHRcdHRoaXMubWF5YmVBcHBlbmRTdWJtaXRCdXR0b25WYWx1ZV8oYm9keSk7XG5cdFx0XHRodHRwTWV0aG9kID0gUmVxdWVzdFNjcmVlbi5QT1NUO1xuXHRcdFx0aWYgKFVBLmlzSWVPckVkZ2UpIHtcblx0XHRcdFx0aGVhZGVycy5hZGQoJ0lmLU5vbmUtTWF0Y2gnLCAnXCIwXCInKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Y29uc3QgcmVxdWVzdFBhdGggPSB0aGlzLmZvcm1hdExvYWRQYXRoKHBhdGgpO1xuXHRcdHJldHVybiBBamF4XG5cdFx0XHQucmVxdWVzdChyZXF1ZXN0UGF0aCwgaHR0cE1ldGhvZCwgYm9keSwgaGVhZGVycywgbnVsbCwgdGhpcy50aW1lb3V0KVxuXHRcdFx0LnRoZW4oeGhyID0+IHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTYWZhcmlYSFJQb2x5ZmlsbCgpO1xuXHRcdFx0XHR0aGlzLnNldFJlcXVlc3QoeGhyKTtcblx0XHRcdFx0dGhpcy5hc3NlcnRWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZSh4aHIuc3RhdHVzKTtcblx0XHRcdFx0aWYgKGh0dHBNZXRob2QgPT09IFJlcXVlc3RTY3JlZW4uR0VUICYmIHRoaXMuaXNDYWNoZWFibGUoKSkge1xuXHRcdFx0XHRcdHRoaXMuYWRkQ2FjaGUoeGhyLnJlc3BvbnNlVGV4dCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0eGhyLnJlcXVlc3RQYXRoID0gcmVxdWVzdFBhdGg7XG5cdFx0XHRcdHJldHVybiB4aHIucmVzcG9uc2VUZXh0O1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaCgocmVhc29uKSA9PiB7XG5cdFx0XHRcdHRoaXMucmVtb3ZlU2FmYXJpWEhSUG9seWZpbGwoKTtcblx0XHRcdFx0c3dpdGNoIChyZWFzb24ubWVzc2FnZSkge1xuXHRcdFx0XHRcdGNhc2UgZXJyb3JzLlJFUVVFU1RfVElNRU9VVDpcblx0XHRcdFx0XHRcdHJlYXNvbi50aW1lb3V0ID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgZXJyb3JzLlJFUVVFU1RfRVJST1I6XG5cdFx0XHRcdFx0XHRyZWFzb24ucmVxdWVzdEVycm9yID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgZXJyb3JzLlJFUVVFU1RfUFJFTUFUVVJFX1RFUk1JTkFUSU9OOlxuXHRcdFx0XHRcdFx0cmVhc29uLnJlcXVlc3RFcnJvciA9IHRydWU7XG5cdFx0XHRcdFx0XHRyZWFzb24ucmVxdWVzdFByZW1hdHVyZVRlcm1pbmF0aW9uID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRocm93IHJlYXNvbjtcblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYWRpdGlvbmFsIGRhdGEgdG8gdGhlIGJvZHkgb2YgdGhlIHJlcXVlc3QgaW4gY2FzZSBhIHN1Ym1pdCBidXR0b25cblx0ICogaXMgY2FwdHVyZWQgZHVyaW5nIGZvcm0gc3VibWlzc2lvbi5cblx0ICogQHBhcmFtIHshRm9ybURhdGF9IGJvZHkgVGhlIEZvcm1EYXRhIGNvbnRhaW5pbmcgdGhlIHJlcXVlc3QgYm9keS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0bWF5YmVBcHBlbmRTdWJtaXRCdXR0b25WYWx1ZV8oYm9keSkge1xuXHRcdGNvbnN0IGJ1dHRvbiA9IGdsb2JhbHMuY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudDtcblx0XHRpZiAoYnV0dG9uICYmIGJ1dHRvbi5uYW1lKSB7XG5cdFx0XHRib2R5LmFwcGVuZChidXR0b24ubmFtZSwgYnV0dG9uLnZhbHVlKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVGhlIGZvbGxvd2luZyBtZXRob2QgdHJpZXMgdG8gZXh0cmFjdCB0aGUgcmVzcG9uc2UgdXJsIHZhbHVlIGJ5IGNoZWNraW5nXG5cdCAqIHRoZSBjdXN0b20gcmVzcG9uc2UgaGVhZGVyICdYLVJlcXVlc3QtVVJMJyBpZiBwcm9wZXIgdmFsdWUgaXMgbm90IHByZXNlbnRcblx0ICogaW4gWE1MSHR0cFJlcXVlc3QuIFRoZSB2YWx1ZSBvZiByZXNwb25zZVVSTCB3aWxsIGJlIHRoZSBmaW5hbCBVUkxcblx0ICogb2J0YWluZWQgYWZ0ZXIgYW55IHJlZGlyZWN0cy4gSW50ZXJuZXQgRXhwbG9yZXIsIEVkZ2UgYW5kIFNhZmFyaSA8PSA3XG5cdCAqIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBmZWF0dXJlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBzZWU6XG5cdCAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9YTUxIdHRwUmVxdWVzdC9yZXNwb25zZVVSTFxuXHQgKiBodHRwczovL3hoci5zcGVjLndoYXR3Zy5vcmcvI3RoZS1yZXNwb25zZXVybC1hdHRyaWJ1dGVcblx0ICogQHBhcmFtIHtYTUxIdHRwUmVxdWVzdH0gcmVxdWVzdFxuXHQgKiBAcmV0dXJuIHs/c3RyaW5nfSBSZXNwb25zZSB1cmwgYmVzdCBtYXRjaC5cblx0ICovXG5cdG1heWJlRXh0cmFjdFJlc3BvbnNlVXJsRnJvbVJlcXVlc3QocmVxdWVzdCkge1xuXHRcdHZhciByZXNwb25zZVVybCA9IHJlcXVlc3QucmVzcG9uc2VVUkw7XG5cdFx0aWYgKHJlc3BvbnNlVXJsKSB7XG5cdFx0XHRyZXR1cm4gcmVzcG9uc2VVcmw7XG5cdFx0fVxuXHRcdHJldHVybiByZXF1ZXN0LmdldFJlc3BvbnNlSGVhZGVyKFJlcXVlc3RTY3JlZW4uWF9SRVFVRVNUX1VSTF9IRUFERVIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoaXMgZnVuY3Rpb24gc2V0IGF0dHJpYnV0ZSBkYXRhLXNhZmFyaS10ZW1wLWRpc2FibGVkIHRvIFxuXHQgKiB0cnVlIGFuZCBzZXQgZGlzYWJsZSBhdHRyaWJ1dGUgb2YgYW4gaW5wdXQgdHlwZT1cImZpbGVcIiB0YWdcblx0ICogaXMgdXNlZCBhcyBhIHBvbHlmaWxsIGZvciBpT1MgMTEuMyBTYWZhcmkgLyBtYWNPUyBTYWZhcmkgMTEuMSBcblx0ICogZW1wdHkgPGlucHV0IHR5cGU9XCJmaWxlXCI+IFhIUiBidWcuXG5cdCAqIGh0dHBzOi8vZ2l0aHViLmNvbS9yYWlscy9yYWlscy9pc3N1ZXMvMzI0NDBcblx0ICogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE4NDQ5MFxuXHQgKi9cblx0YWRkU2FmYXJpWEhSUG9seWZpbGwoKSB7XG5cdFx0aWYgKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCAmJiBVQS5pc1NhZmFyaSkge1xuXHRcdFx0bGV0IGlucHV0cyA9IGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwiZmlsZVwiXTpub3QoW2Rpc2FibGVkXSknKTtcblx0XHRcdGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBpbnB1dHMubGVuZ3RoOyBpbmRleCsrKSB7XG5cdFx0XHRcdGxldCBpbnB1dCA9IGlucHV0c1tpbmRleF07XG5cdFx0XHRcdGlmIChpbnB1dC5maWxlcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSgnZGF0YS1zYWZhcmktdGVtcC1kaXNhYmxlZCcsICd0cnVlJyk7XG5cdFx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAnJyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRoaXMgZnVuY3Rpb24gcmVtb3ZlIGF0dHJpYnV0ZSBkYXRhLXNhZmFyaS10ZW1wLWRpc2FibGVkIGFuZCBkaXNhYmxlIGF0dHJpYnV0ZVxuXHQgKiBvZiBhbiBpbnB1dCB0eXBlPVwiZmlsZVwiIHRhZyBpcyB1c2VkIGFzIGEgcG9seWZpbGwgZm9yIGlPUyAxMS4zIFNhZmFyaSAvIG1hY09TIFNhZmFyaSAxMS4xXG5cdCAqIGVtcHR5IDxpbnB1dCB0eXBlPVwiZmlsZVwiPiBYSFIgYnVnLlxuXHQgKiBodHRwczovL2dpdGh1Yi5jb20vcmFpbHMvcmFpbHMvaXNzdWVzLzMyNDQwXG5cdCAqIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xODQ0OTBcblx0ICovXG5cdHJlbW92ZVNhZmFyaVhIUlBvbHlmaWxsKCkge1xuXHRcdGlmIChnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQgJiYgVUEuaXNTYWZhcmkpIHtcblx0XHRcdGxldCBpbnB1dHMgPSBnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbdHlwZT1cImZpbGVcIl1bZGF0YS1zYWZhcmktdGVtcC1kaXNhYmxlZF0nKTtcblx0XHRcdGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBpbnB1dHMubGVuZ3RoOyBpbmRleCsrKSB7XG5cdFx0XHRcdGNvbnN0IGlucHV0ID0gaW5wdXRzW2luZGV4XTtcblx0XHRcdFx0aW5wdXQucmVtb3ZlQXR0cmlidXRlKCdkYXRhLXNhZmFyaS10ZW1wLWRpc2FibGVkJyk7XG5cdFx0XHRcdGlucHV0LnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgaHR0cCBoZWFkZXJzLlxuXHQgKiBAcGFyYW0gez9PYmplY3Q9fSBodHRwSGVhZGVyc1xuXHQgKi9cblx0c2V0SHR0cEhlYWRlcnMoaHR0cEhlYWRlcnMpIHtcblx0XHR0aGlzLmh0dHBIZWFkZXJzID0gaHR0cEhlYWRlcnM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgaHR0cCBtZXRob2QuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaHR0cE1ldGhvZFxuXHQgKi9cblx0c2V0SHR0cE1ldGhvZChodHRwTWV0aG9kKSB7XG5cdFx0dGhpcy5odHRwTWV0aG9kID0gaHR0cE1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHJlcXVlc3Qgb2JqZWN0LlxuXHQgKiBAcGFyYW0gez9PYmplY3R9IHJlcXVlc3Rcblx0ICovXG5cdHNldFJlcXVlc3QocmVxdWVzdCkge1xuXHRcdHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgcmVxdWVzdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cblx0ICogQHBhcmFtIHshbnVtYmVyfSB0aW1lb3V0XG5cdCAqL1xuXHRzZXRUaW1lb3V0KHRpbWVvdXQpIHtcblx0XHR0aGlzLnRpbWVvdXQgPSB0aW1lb3V0O1xuXHR9XG5cbn1cblxuLyoqXG4gKiBIb2xkcyB2YWx1ZSBmb3IgbWV0aG9kIGdldC5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAZGVmYXVsdCAnZ2V0J1xuICogQHN0YXRpY1xuICovXG5SZXF1ZXN0U2NyZWVuLkdFVCA9ICdnZXQnO1xuXG4vKipcbiAqIEhvbGRzIHZhbHVlIGZvciBtZXRob2QgcG9zdC5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAZGVmYXVsdCAncG9zdCdcbiAqIEBzdGF0aWNcbiAqL1xuUmVxdWVzdFNjcmVlbi5QT1NUID0gJ3Bvc3QnO1xuXG4vKipcbiAqIEZhbGxiYWNrIGh0dHAgaGVhZGVyIHRvIHJldHJpZXZlIHJlc3BvbnNlIHJlcXVlc3QgdXJsLlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBkZWZhdWx0ICdYLVJlcXVlc3QtVVJMJ1xuICogQHN0YXRpY1xuICovXG5SZXF1ZXN0U2NyZWVuLlhfUkVRVUVTVF9VUkxfSEVBREVSID0gJ1gtUmVxdWVzdC1VUkwnO1xuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0U2NyZWVuO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgeyBidWlsZEZyYWdtZW50LCBnbG9iYWxFdmFsLCBnbG9iYWxFdmFsU3R5bGVzLCBtYXRjaCB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgQ2FuY2VsbGFibGVQcm9taXNlIGZyb20gJ21ldGFsLXByb21pc2UnO1xuaW1wb3J0IGdsb2JhbHMgZnJvbSAnLi4vZ2xvYmFscy9nbG9iYWxzJztcbmltcG9ydCBSZXF1ZXN0U2NyZWVuIGZyb20gJy4vUmVxdWVzdFNjcmVlbic7XG5pbXBvcnQgU3VyZmFjZSBmcm9tICcuLi9zdXJmYWNlL1N1cmZhY2UnO1xuaW1wb3J0IFVBIGZyb20gJ21ldGFsLXVzZXJhZ2VudCc7XG5pbXBvcnQgVXJpIGZyb20gJ21ldGFsLXVyaSc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi4vdXRpbHMvdXRpbHMnO1xuXG5jbGFzcyBIdG1sU2NyZWVuIGV4dGVuZHMgUmVxdWVzdFNjcmVlbiB7XG5cblx0LyoqXG5cdCAqIFNjcmVlbiBjbGFzcyB0aGF0IHBlcmZvcm0gYSByZXF1ZXN0IGFuZCBleHRyYWN0cyBzdXJmYWNlIGNvbnRlbnRzIGZyb21cblx0ICogdGhlIHJlc3BvbnNlIGNvbnRlbnQuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAZXh0ZW5kcyB7UmVxdWVzdFNjcmVlbn1cblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgbWV0YSBzZWxlY3Rvci4gUmVsZXZhbnQgdG8gZXh0cmFjdCA8Y29kZT5tZXRhPC9jb2RlPiB0YWdzXG5cdFx0ICogZWxlbWVudHMgZnJvbSByZXF1ZXN0IGZyYWdtZW50cyB0byB1c2UgYXMgdGhlIHNjcmVlbi5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBtZXRhXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubWV0YVRhZ3NTZWxlY3RvciA9ICdtZXRhJztcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSB0aXRsZSBzZWxlY3Rvci4gUmVsZXZhbnQgdG8gZXh0cmFjdCB0aGUgPGNvZGU+PHRpdGxlPjwvY29kZT5cblx0XHQgKiBlbGVtZW50IGZyb20gcmVxdWVzdCBmcmFnbWVudHMgdG8gdXNlIGFzIHRoZSBzY3JlZW4gdGl0bGUuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgdGl0bGVcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy50aXRsZVNlbGVjdG9yID0gJ3RpdGxlJztcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0YWN0aXZhdGUoKSB7XG5cdFx0c3VwZXIuYWN0aXZhdGUoKTtcblx0XHR0aGlzLnJlbGVhc2VWaXJ0dWFsRG9jdW1lbnQoKTtcblx0XHR0aGlzLnBlbmRpbmdTdHlsZXMgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFsbG9jYXRlcyB2aXJ0dWFsIGRvY3VtZW50IGZvciBjb250ZW50LiBBZnRlciBhbGxvY2F0ZWQgdmlydHVhbCBkb2N1bWVudFxuXHQgKiBjYW4gYmUgYWNjZXNzZWQgYnkgPGNvZGU+dGhpcy52aXJ0dWFsRG9jdW1lbnQ8L2NvZGU+LlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGh0bWxTdHJpbmdcblx0ICovXG5cdGFsbG9jYXRlVmlydHVhbERvY3VtZW50Rm9yQ29udGVudChodG1sU3RyaW5nKSB7XG5cdFx0aWYgKCF0aGlzLnZpcnR1YWxEb2N1bWVudCkge1xuXHRcdFx0dGhpcy52aXJ0dWFsRG9jdW1lbnQgPSBnbG9iYWxzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2h0bWwnKTtcblx0XHR9XG5cblx0XHR0aGlzLmNvcHlOb2RlQXR0cmlidXRlc0Zyb21Db250ZW50XyhodG1sU3RyaW5nLCB0aGlzLnZpcnR1YWxEb2N1bWVudCk7XG5cblx0XHR0aGlzLnZpcnR1YWxEb2N1bWVudC5pbm5lckhUTUwgPSBodG1sU3RyaW5nO1xuXHR9XG5cblx0LyoqXG5cdCAqIEN1c3RvbWl6ZXMgbG9naWMgdG8gYXBwZW5kIHN0eWxlcyBpbnRvIGRvY3VtZW50LiBSZWxldmFudCB0byB3aGVuXG5cdCAqIHRyYWNraW5nIGEgc3R5bGUgYnkgaWQgbWFrZSBzdXJlIHRvIHJlLXBvc2l0aW9ucyB0aGUgbmV3IHN0eWxlIGluIHRoZVxuXHQgKiBzYW1lIGRvbSBvcmRlci5cblx0ICogQHBhcmFtIHtFbGVtZW50fSBuZXdTdHlsZVxuXHQgKi9cblx0YXBwZW5kU3R5bGVJbnRvRG9jdW1lbnRfKG5ld1N0eWxlKSB7XG5cdFx0dmFyIGlzVGVtcG9yYXJ5U3R5bGUgPSBtYXRjaChuZXdTdHlsZSwgSHRtbFNjcmVlbi5zZWxlY3RvcnMuc3R5bGVzVGVtcG9yYXJ5KTtcblx0XHRpZiAoaXNUZW1wb3JhcnlTdHlsZSkge1xuXHRcdFx0dGhpcy5wZW5kaW5nU3R5bGVzLnB1c2gobmV3U3R5bGUpO1xuXHRcdH1cblx0XHRpZiAobmV3U3R5bGUuaWQpIHtcblx0XHRcdHZhciBzdHlsZUluRG9jID0gZ2xvYmFscy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChuZXdTdHlsZS5pZCk7XG5cdFx0XHRpZiAoc3R5bGVJbkRvYykge1xuXHRcdFx0XHRzdHlsZUluRG9jLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld1N0eWxlLCBzdHlsZUluRG9jLm5leHRTaWJsaW5nKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRnbG9iYWxzLmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQobmV3U3R5bGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIElmIGJvZHkgaXMgdXNlZCBhcyBzdXJmYWNlIGZvcmNlcyB0aGUgcmVxdWVzdGVkIGRvY3VtZW50cyB0byBoYXZlIHNhbWUgaWRcblx0ICogb2YgdGhlIGluaXRpYWwgcGFnZS5cblx0ICovXG5cdGFzc2VydFNhbWVCb2R5SWRJblZpcnR1YWxEb2N1bWVudCgpIHtcblx0XHR2YXIgYm9keVN1cmZhY2UgPSB0aGlzLnZpcnR1YWxEb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5Jyk7XG5cdFx0aWYgKCFnbG9iYWxzLmRvY3VtZW50LmJvZHkuaWQpIHtcblx0XHRcdGdsb2JhbHMuZG9jdW1lbnQuYm9keS5pZCA9ICdzZW5uYV9zdXJmYWNlXycgKyBnZXRVaWQoKTtcblx0XHR9XG5cdFx0aWYgKGJvZHlTdXJmYWNlKSB7XG5cdFx0XHRib2R5U3VyZmFjZS5pZCA9IGdsb2JhbHMuZG9jdW1lbnQuYm9keS5pZDtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ29waWVzIGF0dHJpYnV0ZXMgZnJvbSB0aGUgPGh0bWw+IHRhZyBvZiBjb250ZW50IHRvIHRoZSBnaXZlbiBub2RlLlxuXHQgKi9cblx0Y29weU5vZGVBdHRyaWJ1dGVzRnJvbUNvbnRlbnRfKGNvbnRlbnQsIG5vZGUpIHtcblx0XHRjb250ZW50ID0gY29udGVudC5yZXBsYWNlKC9bPF1cXHMqaHRtbC9pZywgJzxzZW5uYScpO1xuXHRcdGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UoL1xcL2h0bWxcXHMqXFw+L2lnLCAnL3Nlbm5hPicpO1xuXHRcdGxldCBwbGFjZWhvbGRlcjtcblx0XHRpZiAoVUEuaXNJZSkge1xuXHRcdFx0Y29uc3QgdGVtcE5vZGUgPSBnbG9iYWxzLmRvY3VtZW50LmNyZWF0ZVJhbmdlKCkuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGNvbnRlbnQpO1xuXHRcdFx0cGxhY2Vob2xkZXIgPSB0ZW1wTm9kZS5xdWVyeVNlbGVjdG9yKCdzZW5uYScpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRub2RlLmlubmVySFRNTCA9IGNvbnRlbnQ7XG5cdFx0XHRwbGFjZWhvbGRlciA9IG5vZGUucXVlcnlTZWxlY3Rvcignc2VubmEnKTtcblx0XHR9XG5cblx0XHRpZiAocGxhY2Vob2xkZXIpIHtcblx0XHRcdHV0aWxzLmNsZWFyTm9kZUF0dHJpYnV0ZXMobm9kZSk7XG5cdFx0XHR1dGlscy5jb3B5Tm9kZUF0dHJpYnV0ZXMocGxhY2Vob2xkZXIsIG5vZGUpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBAT3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLmRpc3Bvc2VQZW5kaW5nU3R5bGVzKCk7XG5cdFx0c3VwZXIuZGlzcG9zZUludGVybmFsKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgcGVuZGluZyBzdHlsZXMgaWYgc2NyZWVuIGdldCBkaXNwb3NlZCBwcmlvciB0byBpdHMgbG9hZGluZy5cblx0ICovXG5cdGRpc3Bvc2VQZW5kaW5nU3R5bGVzKCkge1xuXHRcdGlmICh0aGlzLnBlbmRpbmdTdHlsZXMpIHtcblx0XHRcdHV0aWxzLnJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50KHRoaXMucGVuZGluZ1N0eWxlcyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBPdmVycmlkZVxuXHQgKi9cblx0ZXZhbHVhdGVTY3JpcHRzKHN1cmZhY2VzKSB7XG5cdFx0dmFyIGV2YWx1YXRlVHJhY2tlZFNjcmlwdHMgPSB0aGlzLmV2YWx1YXRlVHJhY2tlZFJlc291cmNlc18oXG5cdFx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdHNJbkVsZW1lbnQsIEh0bWxTY3JlZW4uc2VsZWN0b3JzLnNjcmlwdHMsXG5cdFx0XHRIdG1sU2NyZWVuLnNlbGVjdG9ycy5zY3JpcHRzVGVtcG9yYXJ5LCBIdG1sU2NyZWVuLnNlbGVjdG9ycy5zY3JpcHRzUGVybWFuZW50KTtcblxuXHRcdHJldHVybiBldmFsdWF0ZVRyYWNrZWRTY3JpcHRzLnRoZW4oKCkgPT4gc3VwZXIuZXZhbHVhdGVTY3JpcHRzKHN1cmZhY2VzKSk7XG5cdH1cblxuXHQvKipcblx0ICogQE92ZXJyaWRlXG5cdCAqL1xuXHRldmFsdWF0ZVN0eWxlcyhzdXJmYWNlcykge1xuXHRcdHRoaXMucGVuZGluZ1N0eWxlcyA9IFtdO1xuXHRcdHZhciBldmFsdWF0ZVRyYWNrZWRTdHlsZXMgPSB0aGlzLmV2YWx1YXRlVHJhY2tlZFJlc291cmNlc18oXG5cdFx0XHRnbG9iYWxFdmFsU3R5bGVzLnJ1blN0eWxlc0luRWxlbWVudCwgSHRtbFNjcmVlbi5zZWxlY3RvcnMuc3R5bGVzLFxuXHRcdFx0SHRtbFNjcmVlbi5zZWxlY3RvcnMuc3R5bGVzVGVtcG9yYXJ5LCBIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXNQZXJtYW5lbnQsXG5cdFx0XHR0aGlzLmFwcGVuZFN0eWxlSW50b0RvY3VtZW50Xy5iaW5kKHRoaXMpKTtcblxuXHRcdHJldHVybiBldmFsdWF0ZVRyYWNrZWRTdHlsZXMudGhlbigoKSA9PiBzdXBlci5ldmFsdWF0ZVN0eWxlcyhzdXJmYWNlcykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFsbG93cyBhIHNjcmVlbiB0byBldmFsdWF0ZSB0aGUgZmF2aWNvbiBzdHlsZSBiZWZvcmUgdGhlIHNjcmVlbiBiZWNvbWVzIHZpc2libGUuXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX1cblx0ICovXG5cdGV2YWx1YXRlRmF2aWNvbl8oKSB7XG5cdFx0Y29uc3QgcmVzb3VyY2VzSW5WaXJ0dWFsID0gdGhpcy52aXJ0dWFsUXVlcnlTZWxlY3RvckFsbF8oSHRtbFNjcmVlbi5zZWxlY3RvcnMuZmF2aWNvbik7XG5cdFx0Y29uc3QgcmVzb3VyY2VzSW5Eb2N1bWVudCA9IHRoaXMucXVlcnlTZWxlY3RvckFsbF8oSHRtbFNjcmVlbi5zZWxlY3RvcnMuZmF2aWNvbik7XG5cblx0XHRyZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuXHRcdFx0dXRpbHMucmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQocmVzb3VyY2VzSW5Eb2N1bWVudCk7XG5cdFx0XHR0aGlzLnJ1bkZhdmljb25JbkVsZW1lbnRfKHJlc291cmNlc0luVmlydHVhbCkudGhlbigoKSA9PiByZXNvbHZlKCkpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0cmFja2VkIHJlc291cmNlcyBpbnNpZGUgaW5jb21pbmcgZnJhZ21lbnQgYW5kIHJlbW92ZSBleGlzdGluZ1xuXHQgKiB0ZW1wb3JhcnkgcmVzb3VyY2VzLlxuXHQgKiBAcGFyYW0gez9mdW5jdGlvbigpfSBhcHBlbmRGbiBGdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGUgaW50byBkb2N1bWVudC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzZWxlY3RvciBTZWxlY3RvciB1c2VkIHRvIGZpbmQgcmVzb3VyY2VzIHRvIHRyYWNrLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yVGVtcG9yYXJ5IFNlbGVjdG9yIHVzZWQgdG8gZmluZCB0ZW1wb3Jhcnlcblx0ICogICAgIHJlc291cmNlcyB0byB0cmFjay5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzZWxlY3RvclBlcm1hbmVudCBTZWxlY3RvciB1c2VkIHRvIGZpbmQgcGVybWFuZW50XG5cdCAqICAgICByZXNvdXJjZXMgdG8gdHJhY2suXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9ufSBvcHRfYXBwZW5kUmVzb3VyY2VGbiBPcHRpb25hbCBmdW5jdGlvbiB1c2VkIHRvXG5cdCAqICAgICBldmFsdWF0ZSBmcmFnbWVudCBjb250YWluaW5nIHJlc291cmNlcy5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfSBEZWZlcnJlZCB0aGF0IHdhaXRzIHJlc291cmNlcyBldmFsdWF0aW9uIHRvXG5cdCAqICAgICBjb21wbGV0ZS5cblx0ICogQHByaXZhdGVcblx0ICovXG5cdGV2YWx1YXRlVHJhY2tlZFJlc291cmNlc18oZXZhbHVhdG9yRm4sIHNlbGVjdG9yLCBzZWxlY3RvclRlbXBvcmFyeSwgc2VsZWN0b3JQZXJtYW5lbnQsIG9wdF9hcHBlbmRSZXNvdXJjZUZuKSB7XG5cdFx0dmFyIHRyYWNrZWQgPSB0aGlzLnZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyhzZWxlY3Rvcik7XG5cdFx0dmFyIHRlbXBvcmFyaWVzSW5Eb2MgPSB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yVGVtcG9yYXJ5KTtcblx0XHR2YXIgcGVybWFuZW50c0luRG9jID0gdGhpcy5xdWVyeVNlbGVjdG9yQWxsXyhzZWxlY3RvclBlcm1hbmVudCk7XG5cblx0XHQvLyBBZGRzIHBlcm1hbmVudCByZXNvdXJjZXMgaW4gZG9jdW1lbnQgdG8gY2FjaGUuXG5cdFx0cGVybWFuZW50c0luRG9jLmZvckVhY2goKHJlc291cmNlKSA9PiB7XG5cdFx0XHR2YXIgcmVzb3VyY2VLZXkgPSB0aGlzLmdldFJlc291cmNlS2V5XyhyZXNvdXJjZSk7XG5cdFx0XHRpZiAocmVzb3VyY2VLZXkpIHtcblx0XHRcdFx0SHRtbFNjcmVlbi5wZXJtYW5lbnRSZXNvdXJjZXNJbkRvY1tyZXNvdXJjZUtleV0gPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0dmFyIGZyYWcgPSBidWlsZEZyYWdtZW50KCk7XG5cdFx0dHJhY2tlZC5mb3JFYWNoKChyZXNvdXJjZSkgPT4ge1xuXHRcdFx0dmFyIHJlc291cmNlS2V5ID0gdGhpcy5nZXRSZXNvdXJjZUtleV8ocmVzb3VyY2UpO1xuXHRcdFx0Ly8gRG8gbm90IGxvYWQgcGVybWFuZW50IHJlc291cmNlcyBpZiBhbHJlYWR5IGluIGRvY3VtZW50LlxuXHRcdFx0aWYgKCFIdG1sU2NyZWVuLnBlcm1hbmVudFJlc291cmNlc0luRG9jW3Jlc291cmNlS2V5XSkge1xuXHRcdFx0XHRmcmFnLmFwcGVuZENoaWxkKHJlc291cmNlKTtcblx0XHRcdH1cblx0XHRcdC8vIElmIHJlc291cmNlIGhhcyBrZXkgYW5kIGlzIHBlcm1hbmVudCBhZGQgdG8gY2FjaGUuXG5cdFx0XHRpZiAocmVzb3VyY2VLZXkgJiYgbWF0Y2gocmVzb3VyY2UsIHNlbGVjdG9yUGVybWFuZW50KSkge1xuXHRcdFx0XHRIdG1sU2NyZWVuLnBlcm1hbmVudFJlc291cmNlc0luRG9jW3Jlc291cmNlS2V5XSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuXHRcdFx0ZXZhbHVhdG9yRm4oZnJhZywgKCkgPT4ge1xuXHRcdFx0XHR1dGlscy5yZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudCh0ZW1wb3Jhcmllc0luRG9jKTtcblx0XHRcdFx0cmVzb2x2ZSgpO1xuXHRcdFx0fSwgb3B0X2FwcGVuZFJlc291cmNlRm4pO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBPdmVycmlkZVxuXHQgKi9cblx0ZmxpcChzdXJmYWNlcykge1xuXHRcdHJldHVybiBzdXBlci5mbGlwKHN1cmZhY2VzKS50aGVuKCgpID0+IHtcblx0XHRcdHV0aWxzLmNsZWFyTm9kZUF0dHJpYnV0ZXMoZ2xvYmFscy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpO1xuXHRcdFx0dXRpbHMuY29weU5vZGVBdHRyaWJ1dGVzKHRoaXMudmlydHVhbERvY3VtZW50LCBnbG9iYWxzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCk7XG5cdFx0XHR0aGlzLmV2YWx1YXRlRmF2aWNvbl8oKTtcblx0XHRcdHRoaXMudXBkYXRlTWV0YVRhZ3NfKCk7XG5cdFx0fSk7XG5cdH1cblxuXHR1cGRhdGVNZXRhVGFnc18oKSB7XG5cdFx0Y29uc3QgY3VycmVudE1ldGFOb2RlcyA9IHRoaXMucXVlcnlTZWxlY3RvckFsbF8oJ21ldGEnKTtcblx0XHRjb25zdCBtZXRhc0Zyb21WaXJ0dWFsRG9jdW1lbnQgPSB0aGlzLm1ldGFzO1xuXHRcdGlmIChjdXJyZW50TWV0YU5vZGVzKSB7XG5cdFx0XHR1dGlscy5yZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudChjdXJyZW50TWV0YU5vZGVzKTtcblx0XHRcdGlmIChtZXRhc0Zyb21WaXJ0dWFsRG9jdW1lbnQpIHtcblx0XHRcdFx0bWV0YXNGcm9tVmlydHVhbERvY3VtZW50LmZvckVhY2goKG1ldGEpID0+IGdsb2JhbHMuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChtZXRhKSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIGEga2V5IHRvIGlkZW50aWZ5IHRoZSByZXNvdXJjZSBiYXNlZCBvbiBpdHMgYXR0cmlidXRlcy5cblx0ICogQHBhcmFtIHtFbGVtZW50fSByZXNvdXJjZVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEV4dHJhY3RlZCBrZXkgYmFzZWQgb24gcmVzb3VyY2UgYXR0cmlidXRlcyBpbiBvcmRlciBvZlxuXHQgKiAgICAgcHJlZmVyZW5jZTogaWQsIGhyZWYsIHNyYy5cblx0ICovXG5cdGdldFJlc291cmNlS2V5XyhyZXNvdXJjZSkge1xuXHRcdHJldHVybiByZXNvdXJjZS5pZCB8fCByZXNvdXJjZS5ocmVmIHx8IHJlc291cmNlLnNyYyB8fCAnJztcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0Z2V0U3VyZmFjZUNvbnRlbnQoc3VyZmFjZUlkKSB7XG5cdFx0dmFyIHN1cmZhY2UgPSB0aGlzLnZpcnR1YWxEb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjJyArIHN1cmZhY2VJZCk7XG5cdFx0aWYgKHN1cmZhY2UpIHtcblx0XHRcdHZhciBkZWZhdWx0Q2hpbGQgPSBzdXJmYWNlLnF1ZXJ5U2VsZWN0b3IoJyMnICsgc3VyZmFjZUlkICsgJy0nICsgU3VyZmFjZS5ERUZBVUxUKTtcblx0XHRcdGlmIChkZWZhdWx0Q2hpbGQpIHtcblx0XHRcdFx0cmV0dXJuIGRlZmF1bHRDaGlsZC5pbm5lckhUTUw7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gc3VyZmFjZS5pbm5lckhUTUw7IC8vIElmIGRlZmF1bHQgY29udGVudCBub3QgZm91bmQsIHVzZSBzdXJmYWNlIGNvbnRlbnRcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgdGl0bGUgc2VsZWN0b3IuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRUaXRsZVNlbGVjdG9yKCkge1xuXHRcdHJldHVybiB0aGlzLnRpdGxlU2VsZWN0b3I7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGxvYWQocGF0aCkge1xuXHRcdHJldHVybiBzdXBlci5sb2FkKHBhdGgpXG5cdFx0XHQudGhlbihjb250ZW50ID0+IHtcblx0XHRcdFx0dGhpcy5hbGxvY2F0ZVZpcnR1YWxEb2N1bWVudEZvckNvbnRlbnQoY29udGVudCk7XG5cdFx0XHRcdHRoaXMucmVzb2x2ZVRpdGxlRnJvbVZpcnR1YWxEb2N1bWVudCgpO1xuXHRcdFx0XHR0aGlzLnJlc29sdmVNZXRhVGFnc0Zyb21WaXJ0dWFsRG9jdW1lbnQoKTtcblx0XHRcdFx0dGhpcy5hc3NlcnRTYW1lQm9keUlkSW5WaXJ0dWFsRG9jdW1lbnQoKTtcblx0XHRcdFx0aWYgKFVBLmlzSWUpIHtcblx0XHRcdFx0XHR0aGlzLm1ha2VUZW1wb3JhcnlTdHlsZXNIcmVmc1VuaXF1ZV8oKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29udGVudDtcblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFF1ZXJpZXMgdGVtcG9yYXJ5IHN0eWxlcyBmcm9tIHZpcnR1YWwgZG9jdW1lbnQsIGFuZCBtYWtlcyB0aGVtIHVuaXF1ZS5cblx0ICogVGhpcyBpcyBuZWNlc3NhcnkgZm9yIGNhY2hpbmcgYW5kIGxvYWQgZXZlbnQgZmlyaW5nIGlzc3VlcyBzcGVjaWZpYyB0b1xuXHQgKiBJRTExLiBodHRwczovL2RldmVsb3Blci5taWNyb3NvZnQuY29tL2VuLXVzL21pY3Jvc29mdC1lZGdlL3BsYXRmb3JtL2lzc3Vlcy83OTQwMTcxL1xuXHQgKi9cblx0bWFrZVRlbXBvcmFyeVN0eWxlc0hyZWZzVW5pcXVlXygpIHtcblx0XHR2YXIgdGVtcG9yYXJpZXNJbkRvYyA9IHRoaXMudmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfKEh0bWxTY3JlZW4uc2VsZWN0b3JzLnN0eWxlc1RlbXBvcmFyeSk7XG5cdFx0dGVtcG9yYXJpZXNJbkRvYy5mb3JFYWNoKChzdHlsZSkgPT4gdGhpcy5yZXBsYWNlU3R5bGVBbmRNYWtlVW5pcXVlXyhzdHlsZSkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBuZXcgZWxlbWVudCBmcm9tIGdpdmVuLCBjb3BpZXMgYXR0cmlidXRlcywgbXV0YXRlcyBocmVmIHRvIGJlXG5cdCAqIHVuaXF1ZSB0byBwcmV2ZW50IGNhY2hpbmcgYW5kIG1vcmUgdGhhbiBvbmUgbG9hZC9lcnJvciBldmVudCBmcm9tIGZpcmluZy5cblx0ICovXG5cdHJlcGxhY2VTdHlsZUFuZE1ha2VVbmlxdWVfKHN0eWxlKSB7XG5cdFx0aWYgKHN0eWxlLmhyZWYpIHtcblx0XHRcdHZhciBuZXdTdHlsZSA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChzdHlsZS50YWdOYW1lKTtcblx0XHRcdHN0eWxlLmhyZWYgPSBuZXcgVXJpKHN0eWxlLmhyZWYpLm1ha2VVbmlxdWUoKS50b1N0cmluZygpO1xuXHRcdFx0dXRpbHMuY29weU5vZGVBdHRyaWJ1dGVzKHN0eWxlLCBuZXdTdHlsZSk7XG5cdFx0XHRzdHlsZS5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChuZXdTdHlsZSwgc3R5bGUpO1xuXHRcdFx0c3R5bGUuZGlzYWJsZWQgPSB0cnVlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRoZSBmYXZpY29uIGVsZW1lbnRzIHRvIHRoZSBkb2N1bWVudC5cblx0ICogQHBhcmFtIHshQXJyYXk8RWxlbWVudD59IGVsZW1lbnRzXG5cdCAqIEBwcml2YXRlXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX1cblx0ICovXG5cdHJ1bkZhdmljb25JbkVsZW1lbnRfKGVsZW1lbnRzKSB7XG5cdFx0cmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUpID0+IHtcblx0XHRcdGVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoXG5cdFx0XHRcdFVBLmlzSWUgPyBlbGVtZW50IDogdXRpbHMuc2V0RWxlbWVudFdpdGhSYW5kb21IcmVmKGVsZW1lbnQpXG5cdFx0XHQpKTtcblx0XHRcdHJlc29sdmUoKTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBRdWVyaWVzIGVsZW1lbnRzIGZyb20gdmlydHVhbCBkb2N1bWVudCBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBlbGVtZW50cy5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzZWxlY3RvclxuXHQgKiBAcmV0dXJuIHthcnJheS48RWxlbWVudD59XG5cdCAqL1xuXHR2aXJ0dWFsUXVlcnlTZWxlY3RvckFsbF8oc2VsZWN0b3IpIHtcblx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy52aXJ0dWFsRG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFF1ZXJpZXMgZWxlbWVudHMgZnJvbSBkb2N1bWVudCBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBlbGVtZW50cy5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzZWxlY3RvclxuXHQgKiBAcmV0dXJuIHthcnJheS48RWxlbWVudD59XG5cdCAqL1xuXHRxdWVyeVNlbGVjdG9yQWxsXyhzZWxlY3Rvcikge1xuXHRcdHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChnbG9iYWxzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWxlYXNlcyB2aXJ0dWFsIGRvY3VtZW50IGFsbG9jYXRlZCBmb3IgY29udGVudC5cblx0ICovXG5cdHJlbGVhc2VWaXJ0dWFsRG9jdW1lbnQoKSB7XG5cdFx0dGhpcy52aXJ0dWFsRG9jdW1lbnQgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlc29sdmVzIHRpdGxlIGZyb20gYWxsb2NhdGVkIHZpcnR1YWwgZG9jdW1lbnQuXG5cdCAqL1xuXHRyZXNvbHZlVGl0bGVGcm9tVmlydHVhbERvY3VtZW50KCkge1xuXHRcdGNvbnN0IHRpdGxlID0gdGhpcy52aXJ0dWFsRG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLnRpdGxlU2VsZWN0b3IpO1xuXHRcdGlmICh0aXRsZSkge1xuXHRcdFx0dGhpcy5zZXRUaXRsZSh0aXRsZS50ZXh0Q29udGVudC50cmltKCkpO1xuXHRcdH1cblx0fVxuXG5cdHJlc29sdmVNZXRhVGFnc0Zyb21WaXJ0dWFsRG9jdW1lbnQoKSB7XG5cdFx0Y29uc3QgbWV0YXMgPSB0aGlzLnZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyh0aGlzLm1ldGFUYWdzU2VsZWN0b3IpO1xuXHRcdGlmIChtZXRhcykge1xuXHRcdFx0dGhpcy5zZXRNZXRhcyhtZXRhcyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHRpdGxlIHNlbGVjdG9yLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHRpdGxlU2VsZWN0b3Jcblx0ICovXG5cdHNldFRpdGxlU2VsZWN0b3IodGl0bGVTZWxlY3Rvcikge1xuXHRcdHRoaXMudGl0bGVTZWxlY3RvciA9IHRpdGxlU2VsZWN0b3I7XG5cdH1cblxufVxuXG4vKipcbiAqIEhlbHBlciBzZWxlY3RvciBmb3IgaWdub3JlIGZhdmljb24gd2hlbiBleGlzdCBkYXRhLXNlbm5hLXRyYWNrLlxuICovXG5jb25zdCBpZ25vcmVGYXZpY29uID0gJzpub3QoW3JlbD1cIlNob3J0Y3V0IEljb25cIl0pOm5vdChbcmVsPVwic2hvcnRjdXQgaWNvblwiXSk6bm90KFtyZWw9XCJpY29uXCJdKTpub3QoW2hyZWYkPVwiZmF2aWNvbi5pY29uXCJdKSc7XG5cbi8qKlxuICogSGVscGVyIHNlbGVjdG9ycyBmb3IgdHJhY2tpbmcgcmVzb3VyY2VzLlxuICogQHR5cGUge29iamVjdH1cbiAqIEBwcm90ZWN0ZWRcbiAqIEBzdGF0aWNcbiAqL1xuSHRtbFNjcmVlbi5zZWxlY3RvcnMgPSB7XG5cdGZhdmljb246ICdsaW5rW3JlbD1cIlNob3J0Y3V0IEljb25cIl0sbGlua1tyZWw9XCJzaG9ydGN1dCBpY29uXCJdLGxpbmtbcmVsPVwiaWNvblwiXSxsaW5rW2hyZWYkPVwiZmF2aWNvbi5pY29uXCJdJyxcblx0c2NyaXB0czogJ3NjcmlwdFtkYXRhLXNlbm5hLXRyYWNrXScsXG5cdHNjcmlwdHNQZXJtYW5lbnQ6ICdzY3JpcHRbZGF0YS1zZW5uYS10cmFjaz1cInBlcm1hbmVudFwiXScsXG5cdHNjcmlwdHNUZW1wb3Jhcnk6ICdzY3JpcHRbZGF0YS1zZW5uYS10cmFjaz1cInRlbXBvcmFyeVwiXScsXG5cdHN0eWxlczogYHN0eWxlW2RhdGEtc2VubmEtdHJhY2tdLGxpbmtbZGF0YS1zZW5uYS10cmFja10ke2lnbm9yZUZhdmljb259YCxcblx0c3R5bGVzUGVybWFuZW50OiBgc3R5bGVbZGF0YS1zZW5uYS10cmFjaz1cInBlcm1hbmVudFwiXSxsaW5rW2RhdGEtc2VubmEtdHJhY2s9XCJwZXJtYW5lbnRcIl0ke2lnbm9yZUZhdmljb259YCxcblx0c3R5bGVzVGVtcG9yYXJ5OiBgc3R5bGVbZGF0YS1zZW5uYS10cmFjaz1cInRlbXBvcmFyeVwiXSxsaW5rW2RhdGEtc2VubmEtdHJhY2s9XCJ0ZW1wb3JhcnlcIl0ke2lnbm9yZUZhdmljb259YFxufTtcblxuLyoqXG4gKiBDYWNoZXMgcGVybWFuZW50IHJlc291cmNlIGtleXMuXG4gKiBAdHlwZSB7b2JqZWN0fVxuICogQHByb3RlY3RlZFxuICogQHN0YXRpY1xuICovXG5IdG1sU2NyZWVuLnBlcm1hbmVudFJlc291cmNlc0luRG9jID0ge307XG5cbmV4cG9ydCBkZWZhdWx0IEh0bWxTY3JlZW47XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IERpc3Bvc2FibGUsIGdldFVpZCwgaXNEZWZBbmROb3ROdWxsLCBpc0VsZW1lbnQsIG9iamVjdCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCBkYXRhQXR0cmlidXRlcyBmcm9tICcuL2RhdGFBdHRyaWJ1dGVzJztcbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgQXBwIGZyb20gJy4vQXBwJztcbmltcG9ydCBIdG1sU2NyZWVuIGZyb20gJy4uL3NjcmVlbi9IdG1sU2NyZWVuJztcbmltcG9ydCBSb3V0ZSBmcm9tICcuLi9yb3V0ZS9Sb3V0ZSc7XG5cbmNsYXNzIEFwcERhdGFBdHRyaWJ1dGVIYW5kbGVyIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cblx0LyoqXG5cdCAqIEluaXRpbGl6ZXMgQXBwLCByZWdpc3RlciBzdXJmYWNlcyBhbmQgcm91dGVzIGZyb20gZGF0YSBhdHRyaWJ1dGVzLlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgYXBwIHJlZmVyZW5jZSBpbml0aWFsaXplZCBieSBkYXRhIGF0dHJpYnV0ZXMuXG5cdFx0ICogQHR5cGUge0FwcH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICovXG5cdFx0dGhpcy5hcHAgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGJhc2UgZWxlbWVudCB0byBzZWFyY2ggaW5pdGlhbGl6YXRpb24gZGF0YSBhdHRyaWJ1dGVzLiBUaGlzXG5cdFx0ICogZWxlbWVudCBpcyB0aGUgY29udGFpbmVyIHVzZWQgdG8gZW5hYmxlIGluaXRpYWxpemF0aW9uIGJhc2VkIG9uIHRoZVxuXHRcdCAqIHByZXNlbmNlIG9mIGBkYXRhLXNlbm5hYCBhdHRyaWJ1dGUuXG5cdFx0ICogQHR5cGUge0VsZW1lbnR9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqL1xuXHRcdHRoaXMuYmFzZUVsZW1lbnQgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEluaXRzIGFwcGxpY2F0aW9uIGJhc2VkIG9uIGluZm9ybWF0aW9uIHNjYW5uZWQgZnJvbSBkb2N1bWVudC5cblx0ICovXG5cdGhhbmRsZSgpIHtcblx0XHRpZiAoIWlzRWxlbWVudCh0aGlzLmJhc2VFbGVtZW50KSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdTZW5uYSBkYXRhIGF0dHJpYnV0ZSBoYW5kbGVyIGJhc2UgZWxlbWVudCAnICtcblx0XHRcdFx0J25vdCBzZXQgb3IgaW52YWxpZCwgdHJ5IHNldHRpbmcgYSB2YWxpZCBlbGVtZW50IHRoYXQgJyArXG5cdFx0XHRcdCdjb250YWlucyBhIGBkYXRhLXNlbm5hYCBhdHRyaWJ1dGUuJyk7XG5cdFx0fVxuXG5cdFx0aWYgKCF0aGlzLmJhc2VFbGVtZW50Lmhhc0F0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy5zZW5uYSkpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdTZW5uYSB3YXMgbm90IGluaXRpYWxpemVkIGZyb20gZGF0YSBhdHRyaWJ1dGVzLiAnICtcblx0XHRcdFx0J0luIG9yZGVyIHRvIGVuYWJsZSBpdHMgdXNhZ2UgZnJvbSBkYXRhIGF0dHJpYnV0ZXMgdHJ5IHNldHRpbmcgJyArXG5cdFx0XHRcdCdpbiB0aGUgYmFzZSBlbGVtZW50LCBlLmcuIGA8Ym9keSBkYXRhLXNlbm5hPmAuJyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuYXBwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1Nlbm5hIGFwcCB3YXMgYWxyZWFkeSBpbml0aWFsaXplZC4nKTtcblx0XHR9XG5cblx0XHRjb25zb2xlLmxvZygnU2VubmEgaW5pdGlhbGl6ZWQgZnJvbSBkYXRhIGF0dHJpYnV0ZS4nKTtcblxuXHRcdHRoaXMuYXBwID0gbmV3IEFwcCgpO1xuXHRcdHRoaXMubWF5YmVBZGRSb3V0ZXNfKCk7XG5cdFx0dGhpcy5tYXliZUFkZFN1cmZhY2VzXygpO1xuXHRcdHRoaXMubWF5YmVTZXRCYXNlUGF0aF8oKTtcblx0XHR0aGlzLm1heWJlU2V0TGlua1NlbGVjdG9yXygpO1xuXHRcdHRoaXMubWF5YmVTZXRMb2FkaW5nQ3NzQ2xhc3NfKCk7XG5cdFx0dGhpcy5tYXliZVNldFVwZGF0ZVNjcm9sbFBvc2l0aW9uXygpO1xuXHRcdHRoaXMubWF5YmVEaXNwYXRjaF8oKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBvZiB0aGlzIGluc3RhbmNlJ3Mgb2JqZWN0IHJlZmVyZW5jZXMuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdGlmICh0aGlzLmFwcCkge1xuXHRcdFx0dGhpcy5hcHAuZGlzcG9zZSgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBhcHAgcmVmZXJlbmNlLlxuXHQgKiBAcmV0dXJuIHtBcHB9XG5cdCAqL1xuXHRnZXRBcHAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYXBwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGJhc2UgZWxlbWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gYmFzZUVsZW1lbnRcblx0ICovXG5cdGdldEJhc2VFbGVtZW50KCkge1xuXHRcdHJldHVybiB0aGlzLmJhc2VFbGVtZW50O1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIGFkZHMgYXBwIHJvdXRlcyBmcm9tIGxpbmsgZWxlbWVudHMgdGhhdCBhcmUgYHNlbm5hLXJvdXRlYC5cblx0ICovXG5cdG1heWJlQWRkUm91dGVzXygpIHtcblx0XHR2YXIgcm91dGVzU2VsZWN0b3IgPSAnbGlua1tyZWw9XCJzZW5uYS1yb3V0ZVwiXSc7XG5cdFx0dGhpcy5xdWVyeVNlbGVjdG9yQWxsQXNBcnJheV8ocm91dGVzU2VsZWN0b3IpLmZvckVhY2goKGxpbmspID0+IHRoaXMubWF5YmVQYXJzZUxpbmtSb3V0ZV8obGluaykpO1xuXHRcdGlmICghdGhpcy5hcHAuaGFzUm91dGVzKCkpIHtcblx0XHRcdHRoaXMuYXBwLmFkZFJvdXRlcyhuZXcgUm91dGUoLy4qLywgSHRtbFNjcmVlbikpO1xuXHRcdFx0Y29uc29sZS5sb2coJ1Nlbm5hIGNhblxcJ3QgZmluZCByb3V0ZSBlbGVtZW50cywgYWRkaW5nIGRlZmF1bHQuJyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIGFkZHMgYXBwIHN1cmZhY2VzIGJ5IHNjYW5uaW5nIGBkYXRhLXNlbm5hLXN1cmZhY2VgIGRhdGEgYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVBZGRTdXJmYWNlc18oKSB7XG5cdFx0dmFyIHN1cmZhY2VzU2VsZWN0b3IgPSAnWycgKyBkYXRhQXR0cmlidXRlcy5zdXJmYWNlICsgJ10nO1xuXHRcdHRoaXMucXVlcnlTZWxlY3RvckFsbEFzQXJyYXlfKHN1cmZhY2VzU2VsZWN0b3IpLmZvckVhY2goKHN1cmZhY2VFbGVtZW50KSA9PiB7XG5cdFx0XHR0aGlzLnVwZGF0ZUVsZW1lbnRJZElmU3BlY2lhbFN1cmZhY2VfKHN1cmZhY2VFbGVtZW50KTtcblx0XHRcdHRoaXMuYXBwLmFkZFN1cmZhY2VzKHN1cmZhY2VFbGVtZW50LmlkKTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwYXRjaGVzIGFwcCBuYXZpZ2F0aW9uIHRvIHRoZSBjdXJyZW50IHBhdGggd2hlbiBpbml0aWFsaXplcy5cblx0ICovXG5cdG1heWJlRGlzcGF0Y2hfKCkge1xuXHRcdGlmICh0aGlzLmJhc2VFbGVtZW50Lmhhc0F0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy5kaXNwYXRjaCkpIHtcblx0XHRcdHRoaXMuYXBwLmRpc3BhdGNoKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYXBwIHJvdXRlIGJ5IHBhcnNpbmcgdmFsaWQgbGluayBlbGVtZW50cy4gQSB2YWxpZCBsaW5rIGVsZW1lbnQgaXMgb2Zcblx0ICogdGhlIGtpbmQgYHJlbD1cInNlbm5hLXJvdXRlXCJgLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGxpbmtcblx0ICovXG5cdG1heWJlUGFyc2VMaW5rUm91dGVfKGxpbmspIHtcblx0XHR2YXIgcm91dGUgPSBuZXcgUm91dGUodGhpcy5tYXliZVBhcnNlTGlua1JvdXRlUGF0aF8obGluayksIHRoaXMubWF5YmVQYXJzZUxpbmtSb3V0ZUhhbmRsZXJfKGxpbmspKTtcblx0XHR0aGlzLmFwcC5hZGRSb3V0ZXMocm91dGUpO1xuXHRcdGNvbnNvbGUubG9nKCdTZW5uYSBzY2FubmVkIHJvdXRlICcgKyByb3V0ZS5nZXRQYXRoKCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHBhcnNlIGxpbmsgcm91dGUgaGFuZGxlci5cblx0ICogQHBhcmFtIHtFbGVtZW50fSBsaW5rXG5cdCAqIEByZXR1cm4gez9zdHJpbmd9XG5cdCAqL1xuXHRtYXliZVBhcnNlTGlua1JvdXRlSGFuZGxlcl8obGluaykge1xuXHRcdHZhciBoYW5kbGVyID0gbGluay5nZXRBdHRyaWJ1dGUoJ3R5cGUnKTtcblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKGhhbmRsZXIpKSB7XG5cdFx0XHRoYW5kbGVyID0gb2JqZWN0LmdldE9iamVjdEJ5TmFtZShoYW5kbGVyKTtcblx0XHR9XG5cdFx0cmV0dXJuIGhhbmRsZXI7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgcGFyc2UgbGluayByb3V0ZSBwYXRoLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGxpbmtcblx0ICogQHJldHVybiB7P3N0cmluZ31cblx0ICovXG5cdG1heWJlUGFyc2VMaW5rUm91dGVQYXRoXyhsaW5rKSB7XG5cdFx0dmFyIHBhdGggPSBsaW5rLmdldEF0dHJpYnV0ZSgnaHJlZicpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwocGF0aCkpIHtcblx0XHRcdGlmIChwYXRoLmluZGV4T2YoJ3JlZ2V4OicpID09PSAwKSB7XG5cdFx0XHRcdHBhdGggPSBuZXcgUmVnRXhwKHBhdGguc3Vic3RyaW5nKDYpKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgc2V0cyBhcHAgYmFzZSBwYXRoIGZyb20gYGRhdGEtc2VubmEtYmFzZS1wYXRoYCBkYXRhIGF0dHJpYnV0ZS5cblx0ICovXG5cdG1heWJlU2V0QmFzZVBhdGhfKCkge1xuXHRcdHZhciBiYXNlUGF0aCA9IHRoaXMuYmFzZUVsZW1lbnQuZ2V0QXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLmJhc2VQYXRoKTtcblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKGJhc2VQYXRoKSkge1xuXHRcdFx0dGhpcy5hcHAuc2V0QmFzZVBhdGgoYmFzZVBhdGgpO1xuXHRcdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHNjYW5uZWQgYmFzZSBwYXRoICcgKyBiYXNlUGF0aCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHNldHMgYXBwIGxpbmsgc2VsZWN0b3IgZnJvbSBgZGF0YS1zZW5uYS1saW5rLXNlbGVjdG9yYCBkYXRhXG5cdCAqIGF0dHJpYnV0ZS5cblx0ICovXG5cdG1heWJlU2V0TGlua1NlbGVjdG9yXygpIHtcblx0XHR2YXIgbGlua1NlbGVjdG9yID0gdGhpcy5iYXNlRWxlbWVudC5nZXRBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMubGlua1NlbGVjdG9yKTtcblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKGxpbmtTZWxlY3RvcikpIHtcblx0XHRcdHRoaXMuYXBwLnNldExpbmtTZWxlY3RvcihsaW5rU2VsZWN0b3IpO1xuXHRcdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHNjYW5uZWQgbGluayBzZWxlY3RvciAnICsgbGlua1NlbGVjdG9yKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgc2V0cyBhcHAgbGluayBsb2FkaW5nIGNzcyBjbGFzcyBmcm9tIGBkYXRhLXNlbm5hLWxvYWRpbmctY3NzLWNsYXNzYFxuXHQgKiBkYXRhIGF0dHJpYnV0ZS5cblx0ICovXG5cdG1heWJlU2V0TG9hZGluZ0Nzc0NsYXNzXygpIHtcblx0XHR2YXIgbG9hZGluZ0Nzc0NsYXNzID0gdGhpcy5iYXNlRWxlbWVudC5nZXRBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMubG9hZGluZ0Nzc0NsYXNzKTtcblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKGxvYWRpbmdDc3NDbGFzcykpIHtcblx0XHRcdHRoaXMuYXBwLnNldExvYWRpbmdDc3NDbGFzcyhsb2FkaW5nQ3NzQ2xhc3MpO1xuXHRcdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHNjYW5uZWQgbG9hZGluZyBjc3MgY2xhc3MgJyArIGxvYWRpbmdDc3NDbGFzcyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHNldHMgYXBwIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gZnJvbVxuXHQgKiBgZGF0YS1zZW5uYS11cGRhdGUtc2Nyb2xsLXBvc2l0aW9uYCBkYXRhIGF0dHJpYnV0ZS5cblx0ICovXG5cdG1heWJlU2V0VXBkYXRlU2Nyb2xsUG9zaXRpb25fKCkge1xuXHRcdHZhciB1cGRhdGVTY3JvbGxQb3NpdGlvbiA9IHRoaXMuYmFzZUVsZW1lbnQuZ2V0QXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLnVwZGF0ZVNjcm9sbFBvc2l0aW9uKTtcblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKHVwZGF0ZVNjcm9sbFBvc2l0aW9uKSkge1xuXHRcdFx0aWYgKHVwZGF0ZVNjcm9sbFBvc2l0aW9uID09PSAnZmFsc2UnKSB7XG5cdFx0XHRcdHRoaXMuYXBwLnNldFVwZGF0ZVNjcm9sbFBvc2l0aW9uKGZhbHNlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuYXBwLnNldFVwZGF0ZVNjcm9sbFBvc2l0aW9uKHRydWUpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHNjYW5uZWQgdXBkYXRlIHNjcm9sbCBwb3NpdGlvbiAnICsgdXBkYXRlU2Nyb2xsUG9zaXRpb24pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBRdWVyaWVzIGVsZW1lbnRzIGZyb20gZG9jdW1lbnQgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgZWxlbWVudHMuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2VsZWN0b3Jcblx0ICogQHJldHVybiB7YXJyYXkuPEVsZW1lbnQ+fVxuXHQgKi9cblx0cXVlcnlTZWxlY3RvckFsbEFzQXJyYXlfKHNlbGVjdG9yKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGdsb2JhbHMuZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZXMgZWxlbWVudCBpZCBpZiBoYW5kbGVkIGFzIHNwZWNpYWwgc3VyZmFjZSBlbGVtZW50LiBTb21lIHN1cmZhY2VzXG5cdCAqIGFyZSBzbGlnaHRseSBkaWZmZXJlbnQgZnJvbSBvdGhlcnMsIGxpa2Ugd2hlbiB0aHJlYXRpbmcgPGNvZGU+Ym9keTwvY29kZT5cblx0ICogYXMgc3VyZmFjZS5cblx0ICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG5cdCAqL1xuXHR1cGRhdGVFbGVtZW50SWRJZlNwZWNpYWxTdXJmYWNlXyhlbGVtZW50KSB7XG5cdFx0aWYgKCFlbGVtZW50LmlkICYmIGVsZW1lbnQgPT09IGdsb2JhbHMuZG9jdW1lbnQuYm9keSkge1xuXHRcdFx0ZWxlbWVudC5pZCA9ICdzZW5uYV9zdXJmYWNlXycgKyBnZXRVaWQoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgYmFzZSBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGJhc2VFbGVtZW50XG5cdCAqL1xuXHRzZXRCYXNlRWxlbWVudChiYXNlRWxlbWVudCkge1xuXHRcdHRoaXMuYmFzZUVsZW1lbnQgPSBiYXNlRWxlbWVudDtcblx0fVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IEFwcERhdGFBdHRyaWJ1dGVIYW5kbGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IEFwcERhdGFBdHRyaWJ1dGVIYW5kbGVyIGZyb20gJy4vQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXInO1xuXG4vKipcbiAqIERhdGEgYXR0cmlidXRlIGhhbmRsZXIuXG4gKiBAdHlwZSB7QXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXJ9XG4gKi9cbnZhciBkYXRhQXR0cmlidXRlSGFuZGxlciA9IG5ldyBBcHBEYXRhQXR0cmlidXRlSGFuZGxlcigpO1xuXG5nbG9iYWxzLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmdW5jdGlvbigpIHtcblx0ZGF0YUF0dHJpYnV0ZUhhbmRsZXIuc2V0QmFzZUVsZW1lbnQoZ2xvYmFscy5kb2N1bWVudC5ib2R5KTtcblx0ZGF0YUF0dHJpYnV0ZUhhbmRsZXIuaGFuZGxlKCk7XG59KTtcblxuZXhwb3J0IGRlZmF1bHQgZGF0YUF0dHJpYnV0ZUhhbmRsZXI7IiwiLyoqXG4gKiBAcmV0dXJucyBTdHJpbmcgY29udGFpbmluZyB0aGUgY3VycmVudCBzZW5uYSB2ZXJzaW9uXG4gKi9cblxuY29uc3QgdmVyc2lvbiA9ICc8JT0gdmVyc2lvbiAlPic7XG5cbmV4cG9ydCBkZWZhdWx0IHZlcnNpb247Il0sIm5hbWVzIjpbImlzRGVmIiwidmFsIiwidW5kZWZpbmVkIiwiaXNEZWZBbmROb3ROdWxsIiwiaXNOdWxsIiwiaXNEb2N1bWVudCIsIm5vZGVUeXBlIiwiaXNGdW5jdGlvbiIsImlzT2JqZWN0IiwidHlwZSIsImlzU3RyaW5nIiwiU3RyaW5nIiwiaXNTZXJ2ZXJTaWRlIiwib3B0aW9ucyIsImNoZWNrRW52Iiwic2VydmVyU2lkZSIsInByb2Nlc3MiLCJicm93c2VyIiwiZW52IiwiTk9ERV9FTlYiLCJhcnJheSIsImFycjEiLCJhcnIyIiwibGVuZ3RoIiwiaSIsImFyciIsIm91dHB1dCIsIkFycmF5IiwiaXNBcnJheSIsImZsYXR0ZW4iLCJwdXNoIiwib2JqIiwiaW5kZXhPZiIsInJ2IiwicmVtb3ZlQXQiLCJwcm90b3R5cGUiLCJzcGxpY2UiLCJjYWxsIiwic3RhcnQiLCJlbmQiLCJzbGljZWQiLCJhc3luYyIsInRocm93RXhjZXB0aW9uIiwiZXhjZXB0aW9uIiwibmV4dFRpY2siLCJydW4iLCJjYWxsYmFjayIsImNvbnRleHQiLCJ3b3JrUXVldWVTY2hlZHVsZWRfIiwicHJvY2Vzc1dvcmtRdWV1ZSIsIndvcmtRdWV1ZV8iLCJXb3JrSXRlbV8iLCJ3b3JrSXRlbXMiLCJ3b3JrSXRlbSIsImZuIiwic2NvcGUiLCJlIiwiY2IiLCJiaW5kIiwid3JhcENhbGxiYWNrXyIsInNldEltbWVkaWF0ZV8iLCJzZXRJbW1lZGlhdGUiLCJnZXRTZXRJbW1lZGlhdGVFbXVsYXRvcl8iLCJDaGFubmVsIiwiTWVzc2FnZUNoYW5uZWwiLCJ3aW5kb3ciLCJwb3N0TWVzc2FnZSIsImFkZEV2ZW50TGlzdGVuZXIiLCJpZnJhbWUiLCJkb2N1bWVudCIsImNyZWF0ZUVsZW1lbnQiLCJzdHlsZSIsImRpc3BsYXkiLCJzcmMiLCJ0aXRsZSIsImRvY3VtZW50RWxlbWVudCIsImFwcGVuZENoaWxkIiwid2luIiwiY29udGVudFdpbmRvdyIsImRvYyIsIm9wZW4iLCJ3cml0ZSIsImNsb3NlIiwibWVzc2FnZSIsIk1hdGgiLCJyYW5kb20iLCJvcmlnaW4iLCJsb2NhdGlvbiIsInByb3RvY29sIiwiaG9zdCIsIm9ubWVzc2FnZSIsImRhdGEiLCJwb3J0MSIsInBvcnQyIiwiY2hhbm5lbCIsImhlYWQiLCJ0YWlsIiwibmV4dCIsInNjcmlwdCIsIm9ucmVhZHlzdGF0ZWNoYW5nZSIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsIkRpc3Bvc2FibGUiLCJkaXNwb3NlZF8iLCJkaXNwb3NlSW50ZXJuYWwiLCJvYmplY3QiLCJ0YXJnZXQiLCJrZXkiLCJzb3VyY2UiLCJhcmdzIiwibmFtZSIsInBhcnRzIiwic3BsaXQiLCJyZWR1Y2UiLCJwYXJ0IiwibWFwcGVkT2JqIiwia2V5cyIsIk9iamVjdCIsIm9iajEiLCJvYmoyIiwia2V5czEiLCJrZXlzMiIsInN0cmluZyIsInN0cjEiLCJzdHIyIiwidGVzdDEiLCJ0b0xvd2VyQ2FzZSIsInRlc3QyIiwic3RyIiwicmVwbGFjZSIsIngiLCJmbG9vciIsInRvU3RyaW5nIiwiYWJzIiwiRGF0ZSIsIm5vdyIsImhhc2giLCJsZW4iLCJjaGFyQ29kZUF0IiwidmFsdWUiLCJzdWJzdHJpbmciLCJNRVRBTF9EQVRBIiwiZG9tRGF0YSIsImVsZW1lbnQiLCJpbml0aWFsVmFsdWUiLCJFdmVudEhhbmRsZSIsImVtaXR0ZXIiLCJldmVudCIsImxpc3RlbmVyIiwiZW1pdHRlcl8iLCJldmVudF8iLCJsaXN0ZW5lcl8iLCJyZW1vdmVMaXN0ZW5lciIsImlzRGlzcG9zZWQiLCJzaW5nbGVBcnJheV8iLCJFdmVudEVtaXR0ZXIiLCJldmVudHNfIiwibGlzdGVuZXJIYW5kbGVyc18iLCJzaG91bGRVc2VGYWNhZGVfIiwiaG9sZGVyIiwiaGFuZGxlciIsImRlZmF1bHRMaXN0ZW5lciIsInZhbGlkYXRlTGlzdGVuZXJfIiwiZXZlbnRzIiwidG9FdmVudHNBcnJheV8iLCJhZGRTaW5nbGVMaXN0ZW5lcl8iLCJydW5MaXN0ZW5lckhhbmRsZXJzXyIsImFkZEhhbmRsZXJfIiwiZ2V0U2hvdWxkVXNlRmFjYWRlIiwiZmFjYWRlIiwicHJldmVudGVkRGVmYXVsdCIsImxpc3RlbmVycyIsImdldFJhd0xpc3RlbmVyc18iLCJzbGljZSIsImFyZ3VtZW50cyIsInJ1bkxpc3RlbmVyc18iLCJidWlsZEZhY2FkZV8iLCJkaXJlY3RMaXN0ZW5lcnMiLCJ0b0FycmF5IiwiY29uY2F0IiwibWFwIiwiYW1vdW50IiwibWFueV8iLCJzZWxmIiwiaGFuZGxlckludGVybmFsIiwiYXBwbHkiLCJsaXN0ZW5lck9iaiIsInJlbW92ZU1hdGNoaW5nTGlzdGVuZXJPYmpzXyIsImFkZExpc3RlbmVyIiwibWFueSIsImxpc3RlbmVyT2JqcyIsImZpbmFsTGlzdGVuZXJzIiwibWF0Y2hlc0xpc3RlbmVyXyIsIm9mZiIsImhhbmRsZXJzIiwiZGVmYXVsdExpc3RlbmVycyIsImRlZmF1bHQiLCJqIiwic2hvdWxkVXNlRmFjYWRlIiwiVHlwZUVycm9yIiwiRXZlbnRFbWl0dGVyUHJveHkiLCJvcmlnaW5FbWl0dGVyIiwidGFyZ2V0RW1pdHRlciIsImJsYWNrbGlzdCIsIndoaXRlbGlzdCIsImJsYWNrbGlzdF8iLCJvcmlnaW5FbWl0dGVyXyIsInBlbmRpbmdFdmVudHNfIiwicHJveGllZEV2ZW50c18iLCJ0YXJnZXRFbWl0dGVyXyIsIndoaXRlbGlzdF8iLCJzdGFydFByb3h5XyIsIm9uIiwicmVtb3ZlTGlzdGVuZXJzXyIsImVtaXQiLCJzaG91bGRQcm94eUV2ZW50XyIsInRyeVRvQWRkTGlzdGVuZXJfIiwiZm9yRWFjaCIsInByb3h5RXZlbnQiLCJvbkxpc3RlbmVyIiwiYWRkTGlzdGVuZXJfIiwiZW1pdE9uVGFyZ2V0XyIsIkV2ZW50SGFuZGxlciIsImV2ZW50SGFuZGxlc18iLCJEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZSIsInNlbGVjdG9yIiwic2VsZWN0b3JfIiwiZGVsZWdhdGluZyIsImdldCIsInNlbGVjdG9ycyIsInJlbW92ZSIsIkRvbUV2ZW50SGFuZGxlIiwiY2FwdHVyZSIsImNhcHR1cmVfIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImVsZW1lbnRzQnlUYWdfIiwic3VwcG9ydENhY2hlXyIsImN1c3RvbUV2ZW50cyIsIkxBU1RfQ09OVEFJTkVSIiwiVVNFX0NBUFRVUkUiLCJhZGRDbGFzc2VzIiwiZWxlbWVudHMiLCJjbGFzc2VzIiwiYWRkQ2xhc3Nlc1dpdGhOYXRpdmVfIiwiY2xhc3NOYW1lIiwiY2xhc3NMaXN0IiwiYWRkIiwiYWRkQ2xhc3Nlc1dpdGhvdXROYXRpdmVfIiwiZWxlbWVudENsYXNzTmFtZSIsImNsYXNzZXNUb0FwcGVuZCIsImFkZEVsZW1lbnRMaXN0ZW5lcl8iLCJldmVudE5hbWUiLCJhZGRTZWxlY3Rvckxpc3RlbmVyXyIsImRlbGVnYXRpbmdEYXRhIiwiYWRkVG9BcnJfIiwiYXR0YWNoRGVsZWdhdGVFdmVudF8iLCJoYW5kbGVEZWxlZ2F0ZUV2ZW50XyIsImNsb3Nlc3QiLCJtYXRjaCIsImFwcGVuZCIsInBhcmVudCIsImNoaWxkIiwiYnVpbGRGcmFnbWVudCIsImlzTm9kZUxpc3RMaWtlIiwiY2hpbGRBcnIiLCJodG1sU3RyaW5nIiwidGVtcERpdiIsImlubmVySFRNTCIsImZpcnN0Q2hpbGQiLCJmcmFnbWVudCIsImNyZWF0ZURvY3VtZW50RnJhZ21lbnQiLCJjb250YWlucyIsImVsZW1lbnQxIiwiZWxlbWVudDIiLCJkZWxlZ2F0ZSIsInNlbGVjdG9yT3JUYXJnZXQiLCJjdXN0b21Db25maWciLCJvcmlnaW5hbEV2ZW50IiwiZGVmYXVsdExpc3RlbmVyXyIsImlzQWJsZVRvSW50ZXJhY3RXaXRoXyIsIm5vZGUiLCJldmVudE9iaiIsImJ1dHRvbiIsIm1hdGNoZXNTZWxlY3RvciIsInRhZ05hbWUiLCJkaXNhYmxlZCIsIml0ZW0iLCJleGl0RG9jdW1lbnQiLCJyZXQiLCJjb250YWluZXIiLCJjdXJyZW50VGFyZ2V0IiwiZGVmRm5zIiwidHJpZ2dlckRlbGVnYXRlZExpc3RlbmVyc18iLCJ0cmlnZ2VyRGVmYXVsdERlbGVnYXRlZExpc3RlbmVyc18iLCJkZWxlZ2F0ZVRhcmdldCIsInAiLCJFbGVtZW50IiwibSIsIm1hdGNoZXMiLCJ3ZWJraXRNYXRjaGVzU2VsZWN0b3IiLCJtb3pNYXRjaGVzU2VsZWN0b3IiLCJtc01hdGNoZXNTZWxlY3RvciIsIm9NYXRjaGVzU2VsZWN0b3IiLCJtYXRjaEZhbGxiYWNrXyIsIm5vZGVzIiwicXVlcnlTZWxlY3RvckFsbCIsIm5vcm1hbGl6ZURlbGVnYXRlRXZlbnRfIiwic3RvcFByb3BhZ2F0aW9uIiwic3RvcFByb3BhZ2F0aW9uXyIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbl8iLCJvbmNlIiwiZG9tRXZlbnRIYW5kbGUiLCJyZWdpc3RlckN1c3RvbUV2ZW50IiwicmVtb3ZlQ2hpbGRyZW4iLCJyZW1vdmVDbGFzc2VzIiwicmVtb3ZlQ2xhc3Nlc1dpdGhOYXRpdmVfIiwicmVtb3ZlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfIiwidHJpbSIsInN0b3BwZWQiLCJzdG9wcGVkSW1tZWRpYXRlIiwic3VwcG9ydHNFdmVudCIsInRhZyIsImhhc093blByb3BlcnR5IiwiZGVmYXVsdFByZXZlbnRlZCIsImRlZmF1bHRGbnMiLCJjdXJyRWxlbWVudCIsImxpbWl0IiwidHJpZ2dlckVsZW1lbnRMaXN0ZW5lcnNfIiwidHJpZ2dlclNlbGVjdG9yTGlzdGVuZXJzXyIsImxhc3RDb250YWluZXIiLCJ0cmlnZ2VyTGlzdGVuZXJzXyIsIkRvbUV2ZW50RW1pdHRlclByb3h5IiwiaXNEZWxlZ2F0ZUV2ZW50XyIsImluZGV4Iiwic3Vic3RyIiwiYmFiZWxIZWxwZXJzLmdldCIsImlzU3VwcG9ydGVkRG9tRXZlbnRfIiwiZmVhdHVyZXMiLCJhbmltYXRpb25FdmVudE5hbWVfIiwiY2hlY2tBbmltYXRpb25FdmVudE5hbWVfIiwicHJlZml4ZXMiLCJ0eXBlVGl0bGVDYXNlIiwicmVwbGFjZUludGVydmFsIiwidG9VcHBlckNhc2UiLCJzdWZmaXhlcyIsImFuaW1hdGlvbkVsZW1lbnRfIiwiYXR0ck9yZGVyQ2hhbmdlXyIsIm9yaWdpbmFsQ29udGVudCIsImdsb2JhbEV2YWwiLCJ0ZXh0IiwiYXBwZW5kRm4iLCJkZWZhdWx0Rm4iLCJydW5GaWxlIiwic2NyaXB0cyIsInJ1blNjcmlwdHNJbk9yZGVyIiwicnVuU2NyaXB0IiwiZ2xvYmFsRXZhbFN0eWxlcyIsImhyZWYiLCJsaW5rIiwicmVsIiwicnVuU3R5bGUiLCJzdHlsZXMiLCJsb2FkQ291bnQiLCJyZWdpc3RlckV2ZW50cyIsIm1vdXNlRXZlbnRNYXAiLCJyZWxhdGVkIiwicmVsYXRlZFRhcmdldCIsImN1c3RvbVR5cGUiLCJhbmltYXRpb25FdmVudE1hcCIsImV2ZW50VHlwZSIsImNoZWNrQW5pbWF0aW9uRXZlbnROYW1lIiwiZ2xvYmFscyIsImNvbXBhdGliaWxpdHlNb2RlRGF0YV8iLCJ1bmlxdWVJZENvdW50ZXJfIiwiVUlEX1BST1BFUlRZIiwiYWJzdHJhY3RNZXRob2QiLCJFcnJvciIsImRpc2FibGVDb21wYXRpYmlsaXR5TW9kZSIsImVuYWJsZUNvbXBhdGliaWxpdHlNb2RlIiwiZ2V0Q29tcGF0aWJpbGl0eU1vZGVEYXRhIiwiX19NRVRBTF9DT01QQVRJQklMSVRZX18iLCJnZXRGaXJzdFRydXRoeV8iLCJhIiwiYiIsImdldEZ1bmN0aW9uTmFtZSIsImdldFN0YXRpY1Byb3BlcnR5IiwiY3RvciIsInByb3BlcnR5TmFtZSIsIm1lcmdlRm4iLCJtZXJnZWROYW1lIiwibWVyZ2VkIiwiX19wcm90b19fIiwiaXNQcm90b3R5cGVPZiIsIkZ1bmN0aW9uIiwiZ2V0VWlkIiwibm9Jbmhlcml0YW5jZSIsImlkIiwiaWRlbnRpdHlGdW5jdGlvbiIsInJldHVyblZhbHVlIiwiaXNCb29sZWFuIiwiaXNEb2N1bWVudEZyYWdtZW50IiwiaXNFbGVtZW50IiwiaXNOdW1iZXIiLCJpc1dpbmRvdyIsImlzUHJvbWlzZSIsInRoZW4iLCJudWxsRnVuY3Rpb24iLCJwYXJzZUZyb21BbmNob3IiLCJvcHRfdXJpIiwidGVzdCIsImhvc3RuYW1lIiwicGFzc3dvcmQiLCJwYXRobmFtZSIsInBvcnQiLCJzZWFyY2giLCJ1c2VybmFtZSIsInBhcnNlIiwiVVJMIiwidXJsIiwiY3JlYXRlIiwiTXVsdGlNYXAiLCJ2YWx1ZXMiLCJzaXplIiwibmFtZXMiLCJKU09OIiwic3RyaW5naWZ5Iiwic2V0IiwiVHJlZU5vZGUiLCJ2YWx1ZV8iLCJwYXJlbnRfIiwiY2hpbGRyZW5fIiwic2V0UGFyZW50IiwiY3VycmVudCIsImdldFBhcmVudCIsImFuY2VzdG9ycyIsImdldENoaWxkcmVuIiwiRU1QVFlfQVJSQVkiLCJkZXB0aCIsInJvb3QiLCJnZXRDaGlsZENvdW50Iiwib3B0X3ByZW9yZGVyRm4iLCJvcHRfcG9zdG9yZGVyRm4iLCJ0cmF2ZXJzZSIsImFzc2VydENoaWxkSGFzTm9QYXJlbnQiLCJwYXJzZUZuXyIsIlVyaSIsIm1heWJlQWRkUHJvdG9jb2xBbmRIb3N0bmFtZV8iLCJtdWx0aW1hcCIsImdldEFsbCIsImFkZFBhcmFtZXRlclZhbHVlIiwiZW5zdXJlUXVlcnlJbml0aWFsaXplZF8iLCJxdWVyeSIsInBhcmFtIiwidXJsRGVjb2RlIiwiZ2V0SG9zdG5hbWUiLCJnZXRQb3J0IiwiSE9TVE5BTUVfUExBQ0VIT0xERVIiLCJnZXRIb3N0IiwiZ2V0UHJvdG9jb2wiLCJxdWVyeXN0cmluZyIsImdldFBhcmFtZXRlck5hbWVzIiwiZ2V0UGFyYW1ldGVyVmFsdWVzIiwiZW5jb2RlVVJJQ29tcG9uZW50Iiwic2V0UGFyYW1ldGVyVmFsdWUiLCJSQU5ET01fUEFSQU0iLCJnZXRSYW5kb21TdHJpbmciLCJERUZBVUxUX1BST1RPQ09MIiwiY2hhckF0IiwicmVtb3ZlUGFyYW1ldGVyIiwiZ2V0UGF0aG5hbWUiLCJnZXRTZWFyY2giLCJnZXRIYXNoIiwicGFyc2VGbiIsImJhc2VQYXRoIiwicGF0aHMiLCJwYXRoIiwiam9pbiIsImRlY29kZVVSSUNvbXBvbmVudCIsImlzU2VjdXJlIiwidXRpbHMiLCJhdHRyaWJ1dGVzIiwiYXR0cmlidXRlIiwic2V0QXR0cmlidXRlIiwiZ2V0Q3VycmVudEJyb3dzZXJQYXRoV2l0aG91dEhhc2giLCJvZmZzZXRMZWZ0Iiwib2Zmc2V0VG9wIiwib2Zmc2V0UGFyZW50IiwidXJpIiwiY3VycmVudEJyb3dzZXJQYXRoIiwiZ2V0VXJsUGF0aFdpdGhvdXRIYXNoIiwiZ2V0VXJsUGF0aCIsImhpc3RvcnkiLCJwdXNoU3RhdGUiLCJlcnIiLCJlcnJvciIsInJlbW92ZUF0dHJpYnV0ZSIsInJlZmVycmVyIiwiZGVmaW5lUHJvcGVydHkiLCJUaGVuYWJsZSIsIklNUExFTUVOVEVEX0JZX1BST1AiLCJhZGRJbXBsZW1lbnRhdGlvbiIsIiRnb29nX1RoZW5hYmxlIiwiaXNJbXBsZW1lbnRlZEJ5IiwicGFydGlhbCIsIm5ld0FyZ3MiLCJDYW5jZWxsYWJsZVByb21pc2UiLCJyZXNvbHZlciIsIm9wdF9jb250ZXh0Iiwic3RhdGVfIiwiU3RhdGVfIiwiUEVORElORyIsInJlc3VsdF8iLCJjYWxsYmFja0VudHJpZXNfIiwiZXhlY3V0aW5nXyIsIlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkiLCJ1bmhhbmRsZWRSZWplY3Rpb25JZF8iLCJoYWRVbmhhbmRsZWRSZWplY3Rpb25fIiwicmVzb2x2ZV8iLCJGVUxGSUxMRUQiLCJyZWFzb24iLCJSRUpFQ1RFRCIsIkNhbGxiYWNrRW50cnlfIiwicmVzb2x2ZSIsIm9wdF92YWx1ZSIsInJlamVjdCIsIm9wdF9yZWFzb24iLCJyYWNlIiwicHJvbWlzZXMiLCJwcm9taXNlIiwiYWxsIiwidG9GdWxmaWxsIiwib25GdWxmaWxsIiwib25SZWplY3QiLCJmaXJzdEZ1bGZpbGxlZCIsInRvUmVqZWN0IiwicmVhc29ucyIsIm9wdF9vbkZ1bGZpbGxlZCIsIm9wdF9vblJlamVjdGVkIiwiYWRkQ2hpbGRQcm9taXNlXyIsInRoZW5BbHdheXMiLCJvblJlc29sdmVkIiwiaGFuZGxlUmVqZWN0aW9uXyIsImFkZENhbGxiYWNrRW50cnlfIiwidGhlbkNhdGNoIiwib25SZWplY3RlZCIsImNhdGNoIiwiY2FuY2VsIiwib3B0X21lc3NhZ2UiLCJDYW5jZWxsYXRpb25FcnJvciIsIklTX0NBTkNFTExBVElPTl9FUlJPUiIsImNhbmNlbEludGVybmFsXyIsImNhbmNlbENoaWxkXyIsImNoaWxkUHJvbWlzZSIsImNoaWxkQ291bnQiLCJjaGlsZEluZGV4IiwiZW50cnkiLCJjYWxsYmFja0VudHJ5IiwiZXhlY3V0ZUNhbGxiYWNrXyIsInNjaGVkdWxlQ2FsbGJhY2tzXyIsIm9uRnVsZmlsbGVkIiwicmVzdWx0IiwidW5ibG9ja0FuZEZ1bGZpbGxfIiwiQkxPQ0tFRCIsInVuYmxvY2tBbmRSZWplY3RfIiwic3RhdGUiLCJ0cnlUaGVuXyIsImFkZFVuaGFuZGxlZFJlamVjdGlvbl8iLCJ0aGVuYWJsZSIsImNhbGxlZCIsImV4ZWN1dGVDYWxsYmFja3NfIiwiZW50cmllcyIsInJlbW92ZVVuaGFuZGxlZFJlamVjdGlvbl8iLCJzZXRUaW1lb3V0Iiwic2V0VW5oYW5kbGVkUmVqZWN0aW9uSGFuZGxlciIsImRlYm91bmNlIiwiZGVsYXkiLCJkZWJvdW5jZWQiLCJjYW5jZWxEZWJvdW5jZSIsIlJFR0VYIiwiY29udmVydE1hdGNoZXNUb09iaiIsImNvbnZlcnRUb2tlbnNUb1JlZ2V4IiwidG9rZW5zIiwicmVnZXgiLCJjb3JlIiwiZXNjYXBlIiwiZW5jbG9zZU5vbkNhcHR1cmluZ0dyb3VwIiwicGF0dGVybiIsInJlcGVhdCIsInByZWZpeCIsIm9wdGlvbmFsIiwiUmVnRXhwIiwibWFrZVRyYWlsaW5nU2xhc2hPcHRpb25hbCIsInJvdXRlT3JUb2tlbnMiLCJyb3V0ZSIsInVubmFtZWRDb3VudCIsImN1cnJQYXRoIiwiZXhlYyIsInBhcmFtUGF0dGVybiIsInVubmFtZWRQYXR0ZXJuIiwibW9kaWZpZXIiLCJ0b1JlZ2V4IiwiZXh0cmFjdERhdGEiLCJwYXJhbUluZGV4IiwiUm91dGUiLCJwYXJzZWREYXRhXyIsImJ1aWxkUGFyc2VkRGF0YV8iLCJDYWNoZWFibGUiLCJjYWNoZSIsImNhY2hlYWJsZSIsImNvbnRlbnQiLCJjbGVhckNhY2hlIiwiU2NyZWVuIiwibWFrZUlkXyIsIm1ldGFzIiwibG9nIiwic3VyZmFjZXMiLCJzSWQiLCJhY3RpdmVDaGlsZCIsInJ1blNjcmlwdHNJbkVsZW1lbnQiLCJ0cmFuc2l0aW9ucyIsInN1cmZhY2UiLCJkZWZlcnJlZCIsInNob3ciLCJTdXJmYWNlIiwiZGVmYXVsdENoaWxkIiwidHJhbnNpdGlvbkZuIiwiZ2V0Q2hpbGQiLCJERUZBVUxUIiwibWF5YmVXcmFwQ29udGVudEFzRGVmYXVsdF8iLCJzY3JlZW5JZCIsIm9wdF9jb250ZW50IiwiY3JlYXRlQ2hpbGQiLCJ0cmFuc2l0aW9uIiwiZ2V0RWxlbWVudCIsImdldEVsZW1lbnRCeUlkIiwiYWRkQ29udGVudCIsImZyb20iLCJ0byIsImRlZmF1bHRUcmFuc2l0aW9uIiwiTmF2aWdhdGlvblN0cmF0ZWd5IiwiQXBwIiwiYWN0aXZlU2NyZWVuIiwiYWN0aXZlUGF0aCIsImFsbG93UHJldmVudE5hdmlnYXRlIiwiYnJvd3NlclBhdGhCZWZvcmVOYXZpZ2F0ZSIsImNhcHR1cmVTY3JvbGxQb3NpdGlvbkZyb21TY3JvbGxFdmVudCIsImRlZmF1bHRUaXRsZSIsImZvcm1TZWxlY3RvciIsImlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCIsImxpbmtTZWxlY3RvciIsImxvYWRpbmdDc3NDbGFzcyIsIm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uU3VwcG9ydGVkIiwibmF2aWdhdGlvblN0cmF0ZWd5IiwiSU1NRURJQVRFIiwiaXNOYXZpZ2F0aW9uUGVuZGluZyIsInBlbmRpbmdOYXZpZ2F0ZSIsInBvcHN0YXRlU2Nyb2xsTGVmdCIsInBvcHN0YXRlU2Nyb2xsVG9wIiwicmVkaXJlY3RQYXRoIiwicm91dGVzIiwic2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlIiwic2NyZWVucyIsInNraXBMb2FkUG9wc3RhdGUiLCJ1cGRhdGVTY3JvbGxQb3NpdGlvbiIsImFwcEV2ZW50SGFuZGxlcnNfIiwib25TY3JvbGxfIiwib25Mb2FkXyIsIm9uUG9wc3RhdGVfIiwib25TdGFydE5hdmlnYXRlXyIsIm9uQmVmb3JlTmF2aWdhdGVfIiwib25CZWZvcmVOYXZpZ2F0ZURlZmF1bHRfIiwib25CZWZvcmVVbmxvYWREZWZhdWx0XyIsInNldExpbmtTZWxlY3RvciIsInNldEZvcm1TZWxlY3RvciIsIm1heWJlT3ZlcmxvYWRCZWZvcmVVbmxvYWRfIiwiZ2V0SWQiLCJpc1dlYlVyaSIsImlzTGlua1NhbWVPcmlnaW5fIiwiaXNTYW1lQmFzZVBhdGhfIiwiaXNDdXJyZW50QnJvd3NlclBhdGgiLCJmaW5kUm91dGUiLCJyZW1vdmVTY3JlZW4iLCJzY3JlZW4iLCJnZXRIYW5kbGVyIiwiY2xlYXJTY3JlZW5zQ2FjaGUiLCJmb3JtRXZlbnRIYW5kbGVyXyIsImxpbmtFdmVudEhhbmRsZXJfIiwicmVtb3ZlQWxsTGlzdGVuZXJzIiwibmF2aWdhdGUiLCJnZXRDdXJyZW50QnJvd3NlclBhdGgiLCJvcHRfcmVwbGFjZUhpc3RvcnkiLCJzdG9wUGVuZGluZ05hdmlnYXRlXyIsIm5leHRTY3JlZW4iLCJjcmVhdGVTY3JlZW5JbnN0YW5jZSIsIm1heWJlUHJldmVudERlYWN0aXZhdGVfIiwibWF5YmVQcmV2ZW50QWN0aXZhdGVfIiwibG9hZCIsIlNDSEVEVUxFX0xBU1QiLCJkZWFjdGl2YXRlIiwicHJlcGFyZU5hdmlnYXRlSGlzdG9yeV8iLCJwcmVwYXJlTmF2aWdhdGVTdXJmYWNlc18iLCJleHRyYWN0UGFyYW1zIiwiZXZhbHVhdGVTdHlsZXMiLCJmbGlwIiwiZXZhbHVhdGVTY3JpcHRzIiwibWF5YmVVcGRhdGVTY3JvbGxQb3NpdGlvblN0YXRlXyIsInN5bmNTY3JvbGxQb3NpdGlvblN5bmNUaGVuQXN5bmNfIiwiZmluYWxpemVOYXZpZ2F0ZV8iLCJoYW5kbGVOYXZpZ2F0ZUVycm9yXyIsInNjaGVkdWxlZE5hdmlnYXRpb24iLCJzaGlmdCIsIm1heWJlTmF2aWdhdGVfIiwiZ2V0Um91dGVQYXRoIiwiYWN0aXZhdGUiLCJpc0NhY2hlYWJsZSIsImNhcHR1cmVkRm9ybUVsZW1lbnQiLCJjYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50IiwibWF0Y2hlc1BhdGgiLCJnZXRJZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGgiLCJnZXRVcmxQYXRoV2l0aG91dEhhc2hBbmRTZWFyY2giLCJzdGFjayIsImhvc3RVcmkiLCJsb2NhdGlvbkhvc3RVcmkiLCJ3aW5uZXIiLCJzd2l0Y2hTY3JvbGxQb3NpdGlvblJhY2UiLCJzY3JvbGxUbyIsInNjcm9sbExlZnQiLCJzY3JvbGxUb3AiLCJuYXRpdmVTY3JvbGxSZXN0b3JhdGlvbl8iLCJzY3JvbGxSZXN0b3JhdGlvbiIsIm1peGluIiwiY2FuTmF2aWdhdGUiLCJpc05hdmlnYXRpb25TY2hlZHVsZWQiLCJtYXliZVNjaGVkdWxlTmF2aWdhdGlvbl8iLCJwcmV2ZW50RGVmYXVsdCIsIm5hdmlnYXRlRmFpbGVkIiwiaXNTY2hlZHVsZWROYXZpZ2F0aW9uIiwib25iZWZvcmV1bmxvYWQiLCJfb25iZWZvcmV1bmxvYWQiLCJfb3ZlcmxvYWRlZCIsImJlZm9yZUFjdGl2YXRlIiwicHJldmVudCIsImJlZm9yZURlYWN0aXZhdGUiLCJhbmNob3JFbGVtZW50IiwiZ2V0Tm9kZU9mZnNldCIsInNhdmVIaXN0b3J5Q3VycmVudFBhZ2VTY3JvbGxQb3NpdGlvbl8iLCJvcHRfZXZlbnQiLCJpc0h0bWw1SGlzdG9yeVN1cHBvcnRlZCIsImZvcm0iLCJyZXBsYWNlSGlzdG9yeSIsImZ1bmMiLCJhbHRLZXkiLCJjdHJsS2V5IiwibWV0YUtleSIsInNoaWZ0S2V5IiwibWV0aG9kIiwiYnV0dG9uU2VsZWN0b3IiLCJhY3RpdmVFbGVtZW50IiwicXVlcnlTZWxlY3RvciIsImFjdGlvbiIsIm1heWJlUmVwb3NpdGlvblNjcm9sbFRvSGFzaGVkQW5jaG9yIiwicmVsb2FkUGFnZSIsInNlbm5hIiwibG9ja0hpc3RvcnlTY3JvbGxQb3NpdGlvbl8iLCJzZXRSZWZlcnJlciIsInNldEhvc3RuYW1lIiwic2V0UG9ydCIsInBhZ2VZT2Zmc2V0IiwicGFnZVhPZmZzZXQiLCJtYXliZURpc2FibGVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbiIsImVuZE5hdmlnYXRlUGF5bG9hZCIsImRvTmF2aWdhdGVfIiwibWF5YmVSZXN0b3JlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb24iLCJnZXRUaXRsZSIsImdldERlZmF1bHRUaXRsZSIsImJlZm9yZVVwZGF0ZUhpc3RvcnlQYXRoIiwiaGlzdG9yeVN0YXRlIiwibWF5YmVSZXN0b3JlUmVkaXJlY3RQYXRoSGFzaF8iLCJ1cGRhdGVIaXN0b3J5XyIsImJlZm9yZVVwZGF0ZUhpc3RvcnlTdGF0ZSIsInBhcmFtcyIsInN1cmZhY2VDb250ZW50IiwiZ2V0U3VyZmFjZUNvbnRlbnQiLCJyZWxvYWQiLCJzdXJmYWNlSWQiLCJkaXNwb3NlIiwicmVwbGFjZVN0YXRlIiwicmVtb3ZlUGF0aFRyYWlsaW5nU2xhc2giLCJvbkRvY1N1Ym1pdERlbGVnYXRlXyIsIm9uRG9jQ2xpY2tEZWxlZ2F0ZV8iLCJzeW5jIiwidGl0bGVOb2RlIiwiQWpheCIsImFsbEhlYWRlcnMiLCJoZWFkZXJzIiwicGFpcnMiLCJib2R5Iiwib3B0X2hlYWRlcnMiLCJvcHRfcGFyYW1zIiwib3B0X3RpbWVvdXQiLCJvcHRfc3luYyIsIm9wdF93aXRoQ3JlZGVudGlhbHMiLCJyZXF1ZXN0IiwiWE1MSHR0cFJlcXVlc3QiLCJwcmV2aW91c1JlYWR5U3RhdGUiLCJQcm9taXNlIiwib25sb2FkIiwiYWJvcnRlZCIsIm9uZXJyb3IiLCJyZWFkeVN0YXRlIiwidGVybWluYXRlZFByZW1hdHVyZWx5IiwiYWJvcnQiLCJ0aW1lb3V0IiwiYWRkUGFyYW1ldGVyc0Zyb21NdWx0aU1hcCIsIndpdGhDcmVkZW50aWFscyIsInNldFJlcXVlc3RIZWFkZXIiLCJzZW5kIiwiZXJyb3JzIiwiSU5WQUxJRF9TVEFUVVMiLCJSRVFVRVNUX0VSUk9SIiwiUkVRVUVTVF9USU1FT1VUIiwiUkVRVUVTVF9QUkVNQVRVUkVfVEVSTUlOQVRJT04iLCJVQSIsIm5hdmlnYXRvciIsInVzZXJBZ2VudCIsInBsYXRmb3JtIiwiaXNNYWMiLCJtYXRjaFBsYXRmb3JtIiwiaXNXaW4iLCJpc09wZXJhIiwibWF0Y2hVc2VyQWdlbnQiLCJpc0llIiwiaXNFZGdlIiwiaXNJZU9yRWRnZSIsImlzQ2hyb21lIiwiaXNTYWZhcmkiLCJpc0ZpcmVmb3giLCJ0ZXN0VXNlckFnZW50IiwiZ2V0TmF0aXZlVXNlckFnZW50IiwiZ2V0TmF0aXZlUGxhdGZvcm0iLCJSZXF1ZXN0U2NyZWVuIiwiaHR0cEhlYWRlcnMiLCJodHRwTWV0aG9kIiwiR0VUIiwic3RhdHVzIiwiaXNWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZSIsImludmFsaWRTdGF0dXMiLCJzdGF0dXNDb2RlIiwiZ2V0UmVxdWVzdFBhdGgiLCJzZXRQcm90b2NvbCIsIm1ha2VVbmlxdWUiLCJnZXRSZXF1ZXN0IiwicmVxdWVzdFBhdGgiLCJyZXNwb25zZVVybCIsIm1heWJlRXh0cmFjdFJlc3BvbnNlVXJsRnJvbVJlcXVlc3QiLCJyZW1vdmVVbmlxdWUiLCJnZXRDYWNoZSIsImhlYWRlciIsImFkZFNhZmFyaVhIUlBvbHlmaWxsIiwiRm9ybURhdGEiLCJtYXliZUFwcGVuZFN1Ym1pdEJ1dHRvblZhbHVlXyIsIlBPU1QiLCJmb3JtYXRMb2FkUGF0aCIsInJlbW92ZVNhZmFyaVhIUlBvbHlmaWxsIiwic2V0UmVxdWVzdCIsInhociIsImFzc2VydFZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlIiwiYWRkQ2FjaGUiLCJyZXNwb25zZVRleHQiLCJyZXF1ZXN0RXJyb3IiLCJyZXF1ZXN0UHJlbWF0dXJlVGVybWluYXRpb24iLCJyZXNwb25zZVVSTCIsImdldFJlc3BvbnNlSGVhZGVyIiwiWF9SRVFVRVNUX1VSTF9IRUFERVIiLCJpbnB1dHMiLCJpbnB1dCIsImZpbGVzIiwiSHRtbFNjcmVlbiIsIm1ldGFUYWdzU2VsZWN0b3IiLCJ0aXRsZVNlbGVjdG9yIiwicmVsZWFzZVZpcnR1YWxEb2N1bWVudCIsInBlbmRpbmdTdHlsZXMiLCJ2aXJ0dWFsRG9jdW1lbnQiLCJjb3B5Tm9kZUF0dHJpYnV0ZXNGcm9tQ29udGVudF8iLCJuZXdTdHlsZSIsImlzVGVtcG9yYXJ5U3R5bGUiLCJzdHlsZXNUZW1wb3JhcnkiLCJzdHlsZUluRG9jIiwiaW5zZXJ0QmVmb3JlIiwibmV4dFNpYmxpbmciLCJib2R5U3VyZmFjZSIsInBsYWNlaG9sZGVyIiwidGVtcE5vZGUiLCJjcmVhdGVSYW5nZSIsImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIsImNsZWFyTm9kZUF0dHJpYnV0ZXMiLCJjb3B5Tm9kZUF0dHJpYnV0ZXMiLCJkaXNwb3NlUGVuZGluZ1N0eWxlcyIsInJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50IiwiZXZhbHVhdGVUcmFja2VkU2NyaXB0cyIsImV2YWx1YXRlVHJhY2tlZFJlc291cmNlc18iLCJzY3JpcHRzVGVtcG9yYXJ5Iiwic2NyaXB0c1Blcm1hbmVudCIsImV2YWx1YXRlVHJhY2tlZFN0eWxlcyIsInJ1blN0eWxlc0luRWxlbWVudCIsInN0eWxlc1Blcm1hbmVudCIsImFwcGVuZFN0eWxlSW50b0RvY3VtZW50XyIsInJlc291cmNlc0luVmlydHVhbCIsInZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyIsImZhdmljb24iLCJyZXNvdXJjZXNJbkRvY3VtZW50IiwicXVlcnlTZWxlY3RvckFsbF8iLCJydW5GYXZpY29uSW5FbGVtZW50XyIsImV2YWx1YXRvckZuIiwic2VsZWN0b3JUZW1wb3JhcnkiLCJzZWxlY3RvclBlcm1hbmVudCIsIm9wdF9hcHBlbmRSZXNvdXJjZUZuIiwidHJhY2tlZCIsInRlbXBvcmFyaWVzSW5Eb2MiLCJwZXJtYW5lbnRzSW5Eb2MiLCJyZXNvdXJjZSIsInJlc291cmNlS2V5IiwiZ2V0UmVzb3VyY2VLZXlfIiwicGVybWFuZW50UmVzb3VyY2VzSW5Eb2MiLCJmcmFnIiwiZXZhbHVhdGVGYXZpY29uXyIsInVwZGF0ZU1ldGFUYWdzXyIsImN1cnJlbnRNZXRhTm9kZXMiLCJtZXRhc0Zyb21WaXJ0dWFsRG9jdW1lbnQiLCJtZXRhIiwiYWxsb2NhdGVWaXJ0dWFsRG9jdW1lbnRGb3JDb250ZW50IiwicmVzb2x2ZVRpdGxlRnJvbVZpcnR1YWxEb2N1bWVudCIsInJlc29sdmVNZXRhVGFnc0Zyb21WaXJ0dWFsRG9jdW1lbnQiLCJhc3NlcnRTYW1lQm9keUlkSW5WaXJ0dWFsRG9jdW1lbnQiLCJtYWtlVGVtcG9yYXJ5U3R5bGVzSHJlZnNVbmlxdWVfIiwicmVwbGFjZVN0eWxlQW5kTWFrZVVuaXF1ZV8iLCJyZXBsYWNlQ2hpbGQiLCJzZXRFbGVtZW50V2l0aFJhbmRvbUhyZWYiLCJzZXRUaXRsZSIsInRleHRDb250ZW50Iiwic2V0TWV0YXMiLCJpZ25vcmVGYXZpY29uIiwiQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXIiLCJhcHAiLCJiYXNlRWxlbWVudCIsImhhc0F0dHJpYnV0ZSIsImRhdGFBdHRyaWJ1dGVzIiwibWF5YmVBZGRSb3V0ZXNfIiwibWF5YmVBZGRTdXJmYWNlc18iLCJtYXliZVNldEJhc2VQYXRoXyIsIm1heWJlU2V0TGlua1NlbGVjdG9yXyIsIm1heWJlU2V0TG9hZGluZ0Nzc0NsYXNzXyIsIm1heWJlU2V0VXBkYXRlU2Nyb2xsUG9zaXRpb25fIiwibWF5YmVEaXNwYXRjaF8iLCJyb3V0ZXNTZWxlY3RvciIsInF1ZXJ5U2VsZWN0b3JBbGxBc0FycmF5XyIsIm1heWJlUGFyc2VMaW5rUm91dGVfIiwiaGFzUm91dGVzIiwiYWRkUm91dGVzIiwic3VyZmFjZXNTZWxlY3RvciIsInN1cmZhY2VFbGVtZW50IiwidXBkYXRlRWxlbWVudElkSWZTcGVjaWFsU3VyZmFjZV8iLCJhZGRTdXJmYWNlcyIsImRpc3BhdGNoIiwibWF5YmVQYXJzZUxpbmtSb3V0ZVBhdGhfIiwibWF5YmVQYXJzZUxpbmtSb3V0ZUhhbmRsZXJfIiwiZ2V0UGF0aCIsImdldEF0dHJpYnV0ZSIsImdldE9iamVjdEJ5TmFtZSIsInNldEJhc2VQYXRoIiwic2V0TG9hZGluZ0Nzc0NsYXNzIiwic2V0VXBkYXRlU2Nyb2xsUG9zaXRpb24iLCJkYXRhQXR0cmlidXRlSGFuZGxlciIsInNldEJhc2VFbGVtZW50IiwiaGFuZGxlIiwidmVyc2lvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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"} \ No newline at end of file +{"version":3,"file":"senna.js","sources":["node_modules/metal-dom/node_modules/metal/src/coreNamed.js","node_modules/metal-dom/node_modules/metal/src/core.js","node_modules/metal-dom/node_modules/metal/src/array/array.js","node_modules/metal-dom/node_modules/metal/src/async/async.js","node_modules/metal-dom/node_modules/metal/src/disposable/Disposable.js","node_modules/metal-dom/node_modules/metal/src/object/object.js","node_modules/metal-dom/node_modules/metal/src/string/string.js","node_modules/metal-dom/src/domData.js","node_modules/metal-dom/node_modules/metal-events/src/EventHandle.js","node_modules/metal-dom/node_modules/metal-events/src/EventEmitter.js","node_modules/metal-dom/node_modules/metal-events/src/EventEmitterProxy.js","node_modules/metal-dom/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/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-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-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-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, like IE11, 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 * IE11 doesn't support Element.classList.add function, this method\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 * IE11 doesn't support Element.closest function, this method\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 * IE11 doesn't support Element.classList.add function, this method\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 * @deprecated Use element1.contains(element2) directly instead of this method\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 * IE11 doesn't support Element.matches function, this method\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 * IE11 doesn't support once event listener option, this method\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 * IE11 doesn't support Element.prepend function, this method\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 * IE11 doesn't support Element.classList, this method\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 * @deprecated Use element1.parentNode.replaceChild(element2, element1)\n * directly instead of this method\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.replaceChild(element2, 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\treturn document.querySelector(selectorOrElement);\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 * IE11 doesn't support Element.classList, this method\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 IE11, Edge) 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 (\n\t\t\tstyle.rel &&\n\t\t\tstyle.rel !== 'stylesheet' &&\n\t\t\tstyle.rel !== 'canonical' &&\n\t\t\tstyle.rel !== 'alternate'\n\t\t) {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tstyle.tagName === 'STYLE' ||\n\t\t\tstyle.rel === 'canonical' ||\n\t\t\tstyle.rel === 'alternate'\n\t\t) {\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 * 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\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};","'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","/*!\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 /**\n * Returns the form data\n * This method can be extended in order to have a custom implementation of the form params\n * @param {!Element} formElement\n * @param {!Element} submittedButtonElement\n * @return {!FormData}\n */\n\tgetFormData(formElement, submittedButtonElement) {\n let formData = new FormData(formElement);\n this.maybeAppendSubmitButtonValue_(formData, submittedButtonElement);\n return formData;\n }\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 = this.getFormData(globals.capturedFormElement, globals.capturedFormButtonElement);\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 * @param {!Element} submittedButtonElement\n * @protected\n\t */\n\tmaybeAppendSubmitButtonValue_(formData, submittedButtonElement) {\n\t\tif (submittedButtonElement && submittedButtonElement.name) {\n formData.append(submittedButtonElement.name, submittedButtonElement.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":["isDef","val","undefined","isDefAndNotNull","isNull","isDocument","nodeType","isFunction","isObject","type","isString","String","isServerSide","options","checkEnv","serverSide","process","browser","env","NODE_ENV","array","arr1","arr2","length","i","arr","output","Array","isArray","flatten","push","obj","indexOf","rv","removeAt","prototype","splice","call","start","end","sliced","async","throwException","exception","nextTick","run","callback","context","workQueueScheduled_","processWorkQueue","workQueue_","WorkItem_","workItems","workItem","fn","scope","e","cb","bind","wrapCallback_","setImmediate_","setImmediate","getSetImmediateEmulator_","Channel","MessageChannel","window","postMessage","addEventListener","iframe","document","createElement","style","display","src","title","documentElement","appendChild","win","contentWindow","doc","open","write","close","message","Math","random","origin","location","protocol","host","onmessage","data","port1","port2","channel","head","tail","next","script","onreadystatechange","parentNode","removeChild","Disposable","disposed_","disposeInternal","object","target","key","source","args","name","parts","split","reduce","part","mappedObj","keys","Object","obj1","obj2","keys1","keys2","string","str1","str2","test1","toLowerCase","test2","str","replace","x","floor","toString","abs","Date","now","hash","len","charCodeAt","value","substring","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","hasOwnProperty","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","compatibilityModeData_","uniqueIdCounter_","UID_PROPERTY","abstractMethod","Error","disableCompatibilityMode","enableCompatibilityMode","getCompatibilityModeData","__METAL_COMPATIBILITY__","getFirstTruthy_","a","b","getFunctionName","getStaticProperty","ctor","propertyName","mergeFn","mergedName","merged","__proto__","isPrototypeOf","Function","getUid","noInheritance","id","identityFunction","returnValue","isBoolean","isDocumentFragment","isElement","isNumber","isWindow","isPromise","then","nullFunction","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","formElement","submittedButtonElement","formData","FormData","maybeAppendSubmitButtonValue_","getCache","header","addSafariXHRPolyfill","getFormData","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,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9jb3JlTmFtZWQuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvY29yZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9hcnJheS9hcnJheS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9hc3luYy9hc3luYy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9kaXNwb3NhYmxlL0Rpc3Bvc2FibGUuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvb2JqZWN0L29iamVjdC5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9zdHJpbmcvc3RyaW5nLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZG9tRGF0YS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRIYW5kbGUuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50RW1pdHRlci5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRFbWl0dGVyUHJveHkuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50SGFuZGxlci5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL0RvbURlbGVnYXRlZEV2ZW50SGFuZGxlLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvRG9tRXZlbnRIYW5kbGUuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9kb21OYW1lZC5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2RvbS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL0RvbUV2ZW50RW1pdHRlclByb3h5LmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZmVhdHVyZXMuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9nbG9iYWxFdmFsLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZ2xvYmFsRXZhbFN0eWxlcy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2V2ZW50cy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9nbG9iYWxzL2dsb2JhbHMuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2NvcmVOYW1lZC5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvY29yZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvYXJyYXkvYXJyYXkuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2FzeW5jL2FzeW5jLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9kaXNwb3NhYmxlL0Rpc3Bvc2FibGUuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL29iamVjdC9vYmplY3QuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL3N0cmluZy9zdHJpbmcuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtdXJpL3NyYy9wYXJzZUZyb21BbmNob3IuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtdXJpL3NyYy9wYXJzZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1zdHJ1Y3RzL3NyYy9NdWx0aU1hcC5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1zdHJ1Y3RzL3NyYy9UcmVlTm9kZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC11cmkvc3JjL1VyaS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy91dGlscy91dGlscy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9hcHAvZGF0YUF0dHJpYnV0ZXMuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZXZlbnRzL3NyYy9FdmVudEhhbmRsZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50RW1pdHRlci5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50RW1pdHRlclByb3h5LmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRIYW5kbGVyLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXByb21pc2Uvc3JjL3Byb21pc2UvUHJvbWlzZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kZWJvdW5jZS9zcmMvZGVib3VuY2UuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtcGF0aC1wYXJzZXIvc3JjL3BhdGhQYXJzZXIuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9zcmMvcm91dGUvUm91dGUuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9zcmMvY2FjaGVhYmxlL0NhY2hlYWJsZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9zY3JlZW4vU2NyZWVuLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL3N1cmZhY2UvU3VyZmFjZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9hcHAvQXBwLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWFqYXgvc3JjL0FqYXguanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9zcmMvZXJyb3JzL2Vycm9ycy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC11c2VyYWdlbnQvc3JjL1VBLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL3NjcmVlbi9SZXF1ZXN0U2NyZWVuLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL3NjcmVlbi9IdG1sU2NyZWVuLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL2FwcC9BcHBEYXRhQXR0cmlidXRlSGFuZGxlci5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9hcHAvZGF0YUF0dHJpYnV0ZUhhbmRsZXIuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9zcmMvYXBwL3ZlcnNpb24uanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBjb3JlIHV0aWxpdHkgZnVuY3Rpb25zLlxuICogQGNvbnN0XG4gKi9cblxubGV0IGNvbXBhdGliaWxpdHlNb2RlRGF0YV87XG5cbi8qKlxuICogQ291bnRlciBmb3IgdW5pcXVlIGlkLlxuICogQHR5cGUge051bWJlcn1cbiAqIEBwcml2YXRlXG4gKi9cbmxldCB1bmlxdWVJZENvdW50ZXJfID0gMTtcblxuLyoqXG4gKiBVbmlxdWUgaWQgcHJvcGVydHkgcHJlZml4LlxuICogQHR5cGUge1N0cmluZ31cbiAqIEBwcm90ZWN0ZWRcbiAqL1xuZXhwb3J0IGNvbnN0IFVJRF9QUk9QRVJUWSA9IGBjb3JlXyR7KE1hdGgucmFuZG9tKCkgKiAxZTkpID4+PiAwfWA7XG5cbi8qKlxuICogV2hlbiBkZWZpbmluZyBhIGNsYXNzIEZvbyB3aXRoIGFuIGFic3RyYWN0IG1ldGhvZCBiYXIoKSwgeW91IGNhbiBkbzpcbiAqIEZvby5wcm90b3R5cGUuYmFyID0gYWJzdHJhY3RNZXRob2RcbiAqXG4gKiBOb3cgaWYgYSBzdWJjbGFzcyBvZiBGb28gZmFpbHMgdG8gb3ZlcnJpZGUgYmFyKCksIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duXG4gKiB3aGVuIGJhcigpIGlzIGludm9rZWQuXG4gKlxuICogQHR5cGUgeyFGdW5jdGlvbn1cbiAqIEB0aHJvd3Mge0Vycm9yfSB3aGVuIGludm9rZWQgdG8gaW5kaWNhdGUgdGhlIG1ldGhvZCBzaG91bGQgYmUgb3ZlcnJpZGRlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFic3RyYWN0TWV0aG9kKCkge1xuXHR0aHJvdyBFcnJvcignVW5pbXBsZW1lbnRlZCBhYnN0cmFjdCBtZXRob2QnKTtcbn1cblxuLyoqXG4gKiBEaXNhYmxlcyBNZXRhbC5qcydzIGNvbXBhdGliaWxpdHkgbW9kZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2FibGVDb21wYXRpYmlsaXR5TW9kZSgpIHtcblx0Y29tcGF0aWJpbGl0eU1vZGVEYXRhXyA9IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBFbmFibGVzIE1ldGFsLmpzJ3MgY29tcGF0aWJpbGl0eSBtb2RlIHdpdGggdGhlIGZvbGxvd2luZyBmZWF0dXJlcyBmcm9tIHJjXG4gKiBhbmQgMS54IHZlcnNpb25zOlxuICogICAgIC0gVXNpbmcgXCJrZXlcIiB0byByZWZlcmVuY2UgY29tcG9uZW50IGluc3RhbmNlcy4gSW4gdGhlIGN1cnJlbnQgdmVyc2lvblxuICogICAgICAgdGhpcyBzaG91bGQgYmUgZG9uZSB2aWEgXCJyZWZcIiBpbnN0ZWFkLiBUaGlzIGFsbG93cyBvbGQgY29kZSBzdGlsbFxuICogICAgICAgdXNpbmcgXCJrZXlcIiB0byBrZWVwIHdvcmtpbmcgbGlrZSBiZWZvcmUuIE5PVEU6IHRoaXMgbWF5IGNhdXNlXG4gKiAgICAgICBwcm9ibGVtcywgc2luY2UgXCJrZXlcIiBpcyBtZWFudCB0byBiZSB1c2VkIGRpZmZlcmVudGx5LiBPbmx5IHVzZSB0aGlzXG4gKiAgICAgICBpZiBpdCdzIG5vdCBwb3NzaWJsZSB0byB1cGdyYWRlIHRoZSBjb2RlIHRvIHVzZSBcInJlZlwiIGluc3RlYWQuXG4gKiBAcGFyYW0ge09iamVjdD19IGRhdGEgT3B0aW9uYWwgb2JqZWN0IHdpdGggZGF0YSB0byBzcGVjaWZ5IG1vcmVcbiAqICAgICBkZXRhaWxzLCBzdWNoIGFzOlxuICogICAgICAgICAtIHJlbmRlcmVycyB7QXJyYXl9IHRoZSB0ZW1wbGF0ZSByZW5kZXJlcnMgdGhhdCBzaG91bGQgYmUgaW5cbiAqICAgICAgICAgICBjb21wYXRpYmlsaXR5IG1vZGUsIGVpdGhlciB0aGVpciBjb25zdHJ1Y3RvcnMgb3Igc3RyaW5nc1xuICogICAgICAgICAgIHJlcHJlc2VudGluZyB0aGVtIChlLmcuICdzb3knIG9yICdqc3gnKS4gQnkgZGVmYXVsdCwgYWxsIHRoZSBvbmVzXG4gKiAgICAgICAgICAgdGhhdCBleHRlbmQgZnJvbSBJbmNyZW1lbnRhbERvbVJlbmRlcmVyLlxuICogQHR5cGUge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuYWJsZUNvbXBhdGliaWxpdHlNb2RlKGRhdGEgPSB7fSkge1xuXHRjb21wYXRpYmlsaXR5TW9kZURhdGFfID0gZGF0YTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBkYXRhIHVzZWQgZm9yIGNvbXBhdGliaWxpdHkgbW9kZSwgb3Igbm90aGluZyBpZiBpdCBoYXNuJ3QgYmVlblxuICogZW5hYmxlZC5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvbXBhdGliaWxpdHlNb2RlRGF0YSgpIHtcblx0Ly8gQ29tcGF0aWJpbGl0eSBtb2RlIGNhbiBiZSBzZXQgdmlhIHRoZSBfX01FVEFMX0NPTVBBVElCSUxJVFlfXyBnbG9iYWwgdmFyLlxuXHRpZiAoY29tcGF0aWJpbGl0eU1vZGVEYXRhXyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5fX01FVEFMX0NPTVBBVElCSUxJVFlfXykge1xuXHRcdFx0ZW5hYmxlQ29tcGF0aWJpbGl0eU1vZGUod2luZG93Ll9fTUVUQUxfQ09NUEFUSUJJTElUWV9fKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGNvbXBhdGliaWxpdHlNb2RlRGF0YV87XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgaWYgaXQncyB0cnV0aHksIG9yIHRoZSBzZWNvbmQgb3RoZXJ3aXNlLlxuICogQHBhcmFtIHsqfSBhXG4gKiBAcGFyYW0geyp9IGJcbiAqIEByZXR1cm4geyp9XG4gKiBAcHJvdGVjdGVkXG4gKi9cbmZ1bmN0aW9uIGdldEZpcnN0VHJ1dGh5XyhhLCBiKSB7XG5cdHJldHVybiBhIHx8IGI7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgbmFtZSBvZiB0aGUgZ2l2ZW4gZnVuY3Rpb24uIElmIHRoZSBjdXJyZW50IGJyb3dzZXIgZG9lc24ndFxuICogc3VwcG9ydCB0aGUgYG5hbWVgIHByb3BlcnR5LCBsaWtlIElFMTEsIHRoaXMgd2lsbCBjYWxjdWxhdGUgaXQgZnJvbSB0aGUgZnVuY3Rpb24nc1xuICogY29udGVudCBzdHJpbmcuXG4gKiBAcGFyYW0geyFmdW5jdGlvbigpfSBmblxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lKGZuKSB7XG5cdGlmICghZm4ubmFtZSkge1xuXHRcdGNvbnN0IHN0ciA9IGZuLnRvU3RyaW5nKCk7XG5cdFx0Zm4ubmFtZSA9IHN0ci5zdWJzdHJpbmcoOSwgc3RyLmluZGV4T2YoJygnKSk7XG5cdH1cblx0cmV0dXJuIGZuLm5hbWU7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgdmFsdWUgb2YgYSBzdGF0aWMgcHJvcGVydHkgaW4gdGhlIGdpdmVuIGNsYXNzLiBUaGUgdmFsdWUgd2lsbCBiZVxuICogaW5oZXJpdGVkIGZyb20gYW5jZXN0b3JzIGFzIGV4cGVjdGVkLCB1bmxlc3MgYSBjdXN0b20gbWVyZ2UgZnVuY3Rpb24gaXMgZ2l2ZW4sXG4gKiB3aGljaCBjYW4gY2hhbmdlIGhvdyB0aGUgc3VwZXIgY2xhc3NlcycgdmFsdWUgZm9yIHRoYXQgcHJvcGVydHkgd2lsbCBiZSBtZXJnZWRcbiAqIHRvZ2V0aGVyLlxuICogVGhlIGZpbmFsIG1lcmdlZCB2YWx1ZSB3aWxsIGJlIHN0b3JlZCBpbiBhbm90aGVyIHByb3BlcnR5LCBzbyB0aGF0IGl0IHdvbid0XG4gKiBiZSByZWNhbGN1bGF0ZWQgZXZlbiBpZiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBtdWx0aXBsZSB0aW1lcy5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGN0b3IgQ2xhc3MgY29uc3RydWN0b3IuXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHlOYW1lIFByb3BlcnR5IG5hbWUgdG8gYmUgbWVyZ2VkLlxuICogQHBhcmFtIHtmdW5jdGlvbigqLCAqKToqPX0gbWVyZ2VGbiBGdW5jdGlvbiB0aGF0IHJlY2VpdmVzIHRoZSBtZXJnZWRcbiAqICAgICB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgc28gZmFyIGFuZCB0aGUgbmV4dCB2YWx1ZSB0byBiZSBtZXJnZWQgdG8gaXQuXG4gKiAgICAgU2hvdWxkIHJldHVybiB0aGVzZSB0d28gbWVyZ2VkIHRvZ2V0aGVyLiBJZiBub3QgcGFzc2VkIHRoZSBmaW5hbCBwcm9wZXJ0eVxuICogICAgIHdpbGwgYmUgdGhlIGZpcnN0IHRydXRoeSB2YWx1ZSBhbW9uZyBhbmNlc3RvcnMuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGF0aWNQcm9wZXJ0eShcblx0Y3Rvcixcblx0cHJvcGVydHlOYW1lLFxuXHRtZXJnZUZuID0gZ2V0Rmlyc3RUcnV0aHlfXG4pIHtcblx0Y29uc3QgbWVyZ2VkTmFtZSA9IHByb3BlcnR5TmFtZSArICdfTUVSR0VEJztcblx0aWYgKCFjdG9yLmhhc093blByb3BlcnR5KG1lcmdlZE5hbWUpKSB7XG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cdFx0bGV0IG1lcmdlZCA9IGN0b3IuaGFzT3duUHJvcGVydHkocHJvcGVydHlOYW1lKVxuXHRcdFx0PyBjdG9yW3Byb3BlcnR5TmFtZV1cblx0XHRcdDogbnVsbDtcblx0XHRpZiAoY3Rvci5fX3Byb3RvX18gJiYgIWN0b3IuX19wcm90b19fLmlzUHJvdG90eXBlT2YoRnVuY3Rpb24pKSB7XG5cdFx0XHRtZXJnZWQgPSBtZXJnZUZuKFxuXHRcdFx0XHRtZXJnZWQsXG5cdFx0XHRcdGdldFN0YXRpY1Byb3BlcnR5KGN0b3IuX19wcm90b19fLCBwcm9wZXJ0eU5hbWUsIG1lcmdlRm4pXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRjdG9yW21lcmdlZE5hbWVdID0gbWVyZ2VkO1xuXHR9XG5cdHJldHVybiBjdG9yW21lcmdlZE5hbWVdO1xufVxuXG4vKipcbiAqIEdldHMgYW4gdW5pcXVlIGlkLiBJZiBgb2JqZWN0YCBhcmd1bWVudCBpcyBwYXNzZWQsIHRoZSBvYmplY3QgaXNcbiAqIG11dGF0ZWQgd2l0aCBhbiB1bmlxdWUgaWQuIENvbnNlY3V0aXZlIGNhbGxzIHdpdGggdGhlIHNhbWUgb2JqZWN0XG4gKiByZWZlcmVuY2Ugd29uJ3QgbXV0YXRlIHRoZSBvYmplY3QgYWdhaW4sIGluc3RlYWQgdGhlIGN1cnJlbnQgb2JqZWN0IHVpZFxuICogcmV0dXJucy4gU2VlIHtAbGluayBVSURfUFJPUEVSVFl9LlxuICogQHBhcmFtIHtPYmplY3Q9fSBvYmplY3QgT3B0aW9uYWwgb2JqZWN0IHRvIGJlIG11dGF0ZWQgd2l0aCB0aGUgdWlkLiBJZlxuICogICAgIG5vdCBzcGVjaWZpZWQgdGhpcyBtZXRob2Qgb25seSByZXR1cm5zIHRoZSB1aWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBub0luaGVyaXRhbmNlIE9wdGlvbmFsIGZsYWcgaW5kaWNhdGluZyBpZiB0aGlzXG4gKiAgICAgb2JqZWN0J3MgdWlkIHByb3BlcnR5IGNhbiBiZSBpbmhlcml0ZWQgZnJvbSBwYXJlbnRzIG9yIG5vdC5cbiAqIEB0aHJvd3Mge0Vycm9yfSB3aGVuIGludm9rZWQgdG8gaW5kaWNhdGUgdGhlIG1ldGhvZCBzaG91bGQgYmUgb3ZlcnJpZGRlbi5cbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFVpZChvYmplY3QsIG5vSW5oZXJpdGFuY2UpIHtcblx0aWYgKG9iamVjdCkge1xuXHRcdGxldCBpZCA9IG9iamVjdFtVSURfUFJPUEVSVFldO1xuXHRcdGlmIChub0luaGVyaXRhbmNlICYmICFvYmplY3QuaGFzT3duUHJvcGVydHkoVUlEX1BST1BFUlRZKSkge1xuXHRcdFx0aWQgPSBudWxsO1xuXHRcdH1cblx0XHRyZXR1cm4gaWQgfHwgKG9iamVjdFtVSURfUFJPUEVSVFldID0gdW5pcXVlSWRDb3VudGVyXysrKTtcblx0fVxuXHRyZXR1cm4gdW5pcXVlSWRDb3VudGVyXysrO1xufVxuXG4vKipcbiAqIFRoZSBpZGVudGl0eSBmdW5jdGlvbi4gUmV0dXJucyBpdHMgZmlyc3QgYXJndW1lbnQuXG4gKiBAcGFyYW0geyo9fSByZXR1cm5WYWx1ZSBUaGUgc2luZ2xlIHZhbHVlIHRoYXQgd2lsbCBiZSByZXR1cm5lZC5cbiAqIEByZXR1cm4gez99IFRoZSBmaXJzdCBhcmd1bWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5RnVuY3Rpb24ocmV0dXJuVmFsdWUpIHtcblx0cmV0dXJuIHJldHVyblZhbHVlO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGEgYm9vbGVhbi5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGJvb2xlYW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Jvb2xlYW4odmFsKSB7XG5cdHJldHVybiB0eXBlb2YgdmFsID09PSAnYm9vbGVhbic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgbm90IHVuZGVmaW5lZC5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGRlZmluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZih2YWwpIHtcblx0cmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBub3QgdW5kZWZpbmVkIG9yIG51bGwuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmQW5kTm90TnVsbCh2YWwpIHtcblx0cmV0dXJuIGlzRGVmKHZhbCkgJiYgIWlzTnVsbCh2YWwpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIGRvY3VtZW50LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RvY3VtZW50KHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC5ub2RlVHlwZSA9PT0gOTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBkb2N1bWVudC1mcmFnbWVudC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEb2N1bWVudEZyYWdtZW50KHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC5ub2RlVHlwZSA9PT0gMTE7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgZG9tIGVsZW1lbnQuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRWxlbWVudCh2YWwpIHtcblx0cmV0dXJuIHZhbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiB2YWwubm9kZVR5cGUgPT09IDE7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGEgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgbnVsbC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdWxsKHZhbCkge1xuXHRyZXR1cm4gdmFsID09PSBudWxsO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWwpIHtcblx0cmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIHdpbmRvdy5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNXaW5kb3codmFsKSB7XG5cdHJldHVybiB2YWwgIT09IG51bGwgJiYgdmFsID09PSB2YWwud2luZG93O1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGFuIG9iamVjdC4gVGhpcyBpbmNsdWRlcyBhcnJheXNcbiAqIGFuZCBmdW5jdGlvbnMuXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBhbiBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09iamVjdCh2YWwpIHtcblx0Y29uc3QgdHlwZSA9IHR5cGVvZiB2YWw7XG5cdHJldHVybiAodHlwZSA9PT0gJ29iamVjdCcgJiYgdmFsICE9PSBudWxsKSB8fCB0eXBlID09PSAnZnVuY3Rpb24nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIFByb21pc2UuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUHJvbWlzZSh2YWwpIHtcblx0cmV0dXJuIHZhbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsLnRoZW4gPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgc3RyaW5nLlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyh2YWwpIHtcblx0cmV0dXJuIHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnIHx8IHZhbCBpbnN0YW5jZW9mIFN0cmluZztcbn1cblxuLyoqXG4gKiBTZXRzIHRvIHRydWUgaWYgcnVubmluZyBpbnNpZGUgTm9kZS5qcyBlbnZpcm9ubWVudCB3aXRoIGV4dHJhIGNoZWNrIGZvclxuICogYHByb2Nlc3MuYnJvd3NlcmAgdG8gc2tpcCBLYXJtYSBydW5uZXIgZW52aXJvbm1lbnQuIEthcm1hIGVudmlyb25tZW50IGhhc1xuICogYHByb2Nlc3NgIGRlZmluZWQgZXZlbiB0aG91Z2ggaXQgcnVucyBvbiB0aGUgYnJvd3Nlci5cbiAqIEBwYXJhbSB7P09iamVjdH0gb3B0aW9ucyBDb250YWlucyBgY2hlY2tFbnZgIHByb3BlcnR5IHdoaWNoIGlmIHRydWUsIGNoZWNrc1xuICogdGhlIE5PREVfRU5WIHZhcmlhYmxlLiBJZiBOT0RFX0VOViBlcXVhbHMgJ3Rlc3QnLCB0aGUgZnVuY3Rpb24gcmV0dXJucyBmYWxzZS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NlcnZlclNpZGUob3B0aW9ucyA9IHtjaGVja0VudjogdHJ1ZX0pIHtcblx0bGV0IHNlcnZlclNpZGUgPSB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgIXByb2Nlc3MuYnJvd3Nlcjtcblx0aWYgKHNlcnZlclNpZGUgJiYgb3B0aW9ucy5jaGVja0Vudikge1xuXHRcdHNlcnZlclNpZGUgPVxuXHRcdFx0dHlwZW9mIHByb2Nlc3MuZW52ICE9PSAndW5kZWZpbmVkJyAmJlxuXHRcdFx0cHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICd0ZXN0Jztcblx0fVxuXHRyZXR1cm4gc2VydmVyU2lkZTtcbn1cblxuLyoqXG4gKiBOdWxsIGZ1bmN0aW9uIHVzZWQgZm9yIGRlZmF1bHQgdmFsdWVzIG9mIGNhbGxiYWNrcywgZXRjLlxuICogQHJldHVybiB7dm9pZH0gTm90aGluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG51bGxGdW5jdGlvbigpIHt9XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIFRoaXMgZmlsZSBleGlzdHMganVzdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIG1ha2luZyBzdXJlIHRoYXQgb2xkXG4vLyBkZWZhdWx0IGltcG9ydHMgZm9yIHRoaXMgZmlsZSBzdGlsbCB3b3JrLiBJdCdzIGJlc3QgdG8gdXNlIHRoZSBuYW1lZCBleHBvcnRzXG4vLyBmb3IgZWFjaCBmdW5jdGlvbiBpbnN0ZWFkIHRob3VnaCwgc2luY2UgdGhhdCBhbGxvd3MgYnVuZGxlcnMgbGlrZSBSb2xsdXAgdG9cbi8vIHJlZHVjZSB0aGUgYnVuZGxlIHNpemUgYnkgcmVtb3ZpbmcgdW51c2VkIGNvZGUuXG5pbXBvcnQgKiBhcyBjb3JlIGZyb20gJy4vY29yZU5hbWVkJztcblxuZXhwb3J0IGRlZmF1bHQgY29yZTtcbmV4cG9ydCB7Y29yZX07XG5leHBvcnQgKiBmcm9tICcuL2NvcmVOYW1lZCc7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3IgYXJyYXkgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBhcnJheSB7XG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGFycmF5cyBoYXZlIHRoZSBzYW1lIGNvbnRlbnQuXG5cdCAqIEBwYXJhbSB7IUFycmF5PCo+fSBhcnIxXG5cdCAqIEBwYXJhbSB7IUFycmF5PCo+fSBhcnIyXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRzdGF0aWMgZXF1YWwoYXJyMSwgYXJyMikge1xuXHRcdGlmIChhcnIxID09PSBhcnIyKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0aWYgKGFycjEubGVuZ3RoICE9PSBhcnIyLmxlbmd0aCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFycjEubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChhcnIxW2ldICE9PSBhcnIyW2ldKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgZmlyc3QgdmFsdWUgaW4gdGhlIGdpdmVuIGFycmF5IHRoYXQgaXNuJ3QgdW5kZWZpbmVkLlxuXHQgKiBAcGFyYW0geyFBcnJheX0gYXJyXG5cdCAqIEByZXR1cm4geyp9XG5cdCAqL1xuXHRzdGF0aWMgZmlyc3REZWZpbmVkVmFsdWUoYXJyKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChhcnJbaV0gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRyZXR1cm4gYXJyW2ldO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUcmFuc2Zvcm1zIHRoZSBpbnB1dCBuZXN0ZWQgYXJyYXkgdG8gYmVjb21lIGZsYXQuXG5cdCAqIEBwYXJhbSB7QXJyYXkuPCp8QXJyYXkuPCo+Pn0gYXJyIE5lc3RlZCBhcnJheSB0byBmbGF0dGVuLlxuXHQgKiBAcGFyYW0ge0FycmF5LjwqPj19IG91dHB1dCBPcHRpb25hbCBvdXRwdXQgYXJyYXkuXG5cdCAqIEByZXR1cm4ge0FycmF5LjwqPn0gRmxhdCBhcnJheS5cblx0ICovXG5cdHN0YXRpYyBmbGF0dGVuKGFyciwgb3V0cHV0ID0gW10pIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKEFycmF5LmlzQXJyYXkoYXJyW2ldKSkge1xuXHRcdFx0XHRhcnJheS5mbGF0dGVuKGFycltpXSwgb3V0cHV0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG91dHB1dC5wdXNoKGFycltpXSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhIHBhcnRpY3VsYXIgdmFsdWUgZnJvbSBhbiBhcnJheS5cblx0ICogQHBhcmFtIHtBcnJheS48VD59IGFyciBBcnJheSBmcm9tIHdoaWNoIHRvIHJlbW92ZSB2YWx1ZS5cblx0ICogQHBhcmFtIHtUfSBvYmogT2JqZWN0IHRvIHJlbW92ZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBhbiBlbGVtZW50IHdhcyByZW1vdmVkLlxuXHQgKiBAdGVtcGxhdGUgVFxuXHQgKi9cblx0c3RhdGljIHJlbW92ZShhcnIsIG9iaikge1xuXHRcdGNvbnN0IGkgPSBhcnIuaW5kZXhPZihvYmopO1xuXHRcdGxldCBydjtcblx0XHRpZiAoKHJ2ID0gaSA+PSAwKSkge1xuXHRcdFx0YXJyYXkucmVtb3ZlQXQoYXJyLCBpKTtcblx0XHR9XG5cdFx0cmV0dXJuIHJ2O1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgZnJvbSBhbiBhcnJheSB0aGUgZWxlbWVudCBhdCBpbmRleCBpXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGFyciBBcnJheSBvciBhcnJheSBsaWtlIG9iamVjdCBmcm9tIHdoaWNoIHRvIHJlbW92ZSB2YWx1ZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGkgVGhlIGluZGV4IHRvIHJlbW92ZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBhbiBlbGVtZW50IHdhcyByZW1vdmVkLlxuXHQgKi9cblx0c3RhdGljIHJlbW92ZUF0KGFyciwgaSkge1xuXHRcdHJldHVybiBBcnJheS5wcm90b3R5cGUuc3BsaWNlLmNhbGwoYXJyLCBpLCAxKS5sZW5ndGggPT09IDE7XG5cdH1cblxuXHQvKipcblx0ICogU2xpY2VzIHRoZSBnaXZlbiBhcnJheSwganVzdCBsaWtlIEFycmF5LnByb3RvdHlwZS5zbGljZSwgYnV0IHRoaXNcblx0ICogaXMgZmFzdGVyIGFuZCB3b3JraW5nIG9uIGFsbCBhcnJheS1saWtlIG9iamVjdHMgKGxpa2UgYXJndW1lbnRzKS5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBhcnIgQXJyYXktbGlrZSBvYmplY3QgdG8gc2xpY2UuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgaW5kZXggdGhhdCBzaG91bGQgc3RhcnQgdGhlIHNsaWNlLlxuXHQgKiBAcGFyYW0ge251bWJlcj19IGVuZCBUaGUgaW5kZXggd2hlcmUgdGhlIHNsaWNlIHNob3VsZCBlbmQsIG5vdFxuXHQgKiAgIGluY2x1ZGVkIGluIHRoZSBmaW5hbCBhcnJheS4gSWYgbm90IGdpdmVuLCBhbGwgZWxlbWVudHMgYWZ0ZXIgdGhlXG5cdCAqICAgc3RhcnQgaW5kZXggd2lsbCBiZSBpbmNsdWRlZC5cblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKi9cblx0c3RhdGljIHNsaWNlKGFyciwgc3RhcnQsIGVuZCA9IGFyci5sZW5ndGgpIHtcblx0XHRjb25zdCBzbGljZWQgPSBbXTtcblx0XHRmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuXHRcdFx0c2xpY2VkLnB1c2goYXJyW2ldKTtcblx0XHR9XG5cdFx0cmV0dXJuIHNsaWNlZDtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBhcnJheTtcbiIsIi8qICFcbiAqIFBvbHlmaWxsIGZyb20gR29vZ2xlJ3MgQ2xvc3VyZSBMaWJyYXJ5LlxuICogQ29weXJpZ2h0IDIwMTMgVGhlIENsb3N1cmUgTGlicmFyeSBBdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtpc1NlcnZlclNpZGV9IGZyb20gJy4uL2NvcmVOYW1lZCc7XG5cbmNvbnN0IGFzeW5jID0ge307XG5cbi8qKlxuICogVGhyb3cgYW4gaXRlbSB3aXRob3V0IGludGVycnVwdGluZyB0aGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dC4gIEZvclxuICogZXhhbXBsZSwgaWYgcHJvY2Vzc2luZyBhIGdyb3VwIG9mIGl0ZW1zIGluIGEgbG9vcCwgc29tZXRpbWVzIGl0IGlzIHVzZWZ1bFxuICogdG8gcmVwb3J0IGFuIGVycm9yIHdoaWxlIHN0aWxsIGFsbG93aW5nIHRoZSByZXN0IG9mIHRoZSBiYXRjaCB0byBiZVxuICogcHJvY2Vzc2VkLlxuICogQHBhcmFtIHsqfSBleGNlcHRpb25cbiAqL1xuYXN5bmMudGhyb3dFeGNlcHRpb24gPSBmdW5jdGlvbihleGNlcHRpb24pIHtcblx0Ly8gRWFjaCB0aHJvdyBuZWVkcyB0byBiZSBpbiBpdHMgb3duIGNvbnRleHQuXG5cdGFzeW5jLm5leHRUaWNrKGZ1bmN0aW9uKCkge1xuXHRcdHRocm93IGV4Y2VwdGlvbjtcblx0fSk7XG59O1xuXG4vKipcbiAqIEZpcmVzIHRoZSBwcm92aWRlZCBjYWxsYmFjayBqdXN0IGJlZm9yZSB0aGUgY3VycmVudCBjYWxsc3RhY2sgdW53aW5kcywgb3IgYXNcbiAqIHNvb24gYXMgcG9zc2libGUgYWZ0ZXIgdGhlIGN1cnJlbnQgSlMgZXhlY3V0aW9uIGNvbnRleHQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6VEhJUyl9IGNhbGxiYWNrXG4gKiBAcGFyYW0ge1RISVM9fSBjb250ZXh0IE9iamVjdCB0byB1c2UgYXMgdGhlIFwidGhpcyB2YWx1ZVwiIHdoZW4gY2FsbGluZ1xuICogICAgIHRoZSBwcm92aWRlZCBmdW5jdGlvbi5cbiAqIEB0ZW1wbGF0ZSBUSElTXG4gKi9cbmFzeW5jLnJ1biA9IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG5cdGlmICghYXN5bmMucnVuLndvcmtRdWV1ZVNjaGVkdWxlZF8pIHtcblx0XHQvLyBOb3RoaW5nIGlzIGN1cnJlbnRseSBzY2hlZHVsZWQsIHNjaGVkdWxlIGl0IG5vdy5cblx0XHRhc3luYy5uZXh0VGljayhhc3luYy5ydW4ucHJvY2Vzc1dvcmtRdWV1ZSk7XG5cdFx0YXN5bmMucnVuLndvcmtRdWV1ZVNjaGVkdWxlZF8gPSB0cnVlO1xuXHR9XG5cblx0YXN5bmMucnVuLndvcmtRdWV1ZV8ucHVzaChuZXcgYXN5bmMucnVuLldvcmtJdGVtXyhjYWxsYmFjaywgY29udGV4dCkpO1xufTtcblxuLyoqIEBwcml2YXRlIHtib29sZWFufSAqL1xuYXN5bmMucnVuLndvcmtRdWV1ZVNjaGVkdWxlZF8gPSBmYWxzZTtcblxuLyoqIEBwcml2YXRlIHshQXJyYXkuPCFhc3luYy5ydW4uV29ya0l0ZW1fPn0gKi9cbmFzeW5jLnJ1bi53b3JrUXVldWVfID0gW107XG5cbi8qKlxuICogUnVuIGFueSBwZW5kaW5nIGFzeW5jLnJ1biB3b3JrIGl0ZW1zLiBUaGlzIGZ1bmN0aW9uIGlzIG5vdCBpbnRlbmRlZFxuICogZm9yIGdlbmVyYWwgdXNlLCBidXQgZm9yIHVzZSBieSBlbnRyeSBwb2ludCBoYW5kbGVycyB0byBydW4gaXRlbXMgYWhlYWQgb2ZcbiAqIGFzeW5jLm5leHRUaWNrLlxuICovXG5hc3luYy5ydW4ucHJvY2Vzc1dvcmtRdWV1ZSA9IGZ1bmN0aW9uKCkge1xuXHQvLyBOT1RFOiBhZGRpdGlvbmFsIHdvcmsgcXVldWUgaXRlbXMgbWF5IGJlIHB1c2hlZCB3aGlsZSBwcm9jZXNzaW5nLlxuXHR3aGlsZSAoYXN5bmMucnVuLndvcmtRdWV1ZV8ubGVuZ3RoKSB7XG5cdFx0Ly8gRG9uJ3QgbGV0IHRoZSB3b3JrIHF1ZXVlIGdyb3cgaW5kZWZpbml0ZWx5LlxuXHRcdGNvbnN0IHdvcmtJdGVtcyA9IGFzeW5jLnJ1bi53b3JrUXVldWVfO1xuXHRcdGFzeW5jLnJ1bi53b3JrUXVldWVfID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB3b3JrSXRlbXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IHdvcmtJdGVtID0gd29ya0l0ZW1zW2ldO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0d29ya0l0ZW0uZm4uY2FsbCh3b3JrSXRlbS5zY29wZSk7XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdGFzeW5jLnRocm93RXhjZXB0aW9uKGUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFRoZXJlIGFyZSBubyBtb3JlIHdvcmsgaXRlbXMsIHJlc2V0IHRoZSB3b3JrIHF1ZXVlLlxuXHRhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IGZhbHNlO1xufTtcblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBmaW5hbFxuICogQHN0cnVjdFxuICogQHByaXZhdGVcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGZuXG4gKiBAcGFyYW0ge09iamVjdHxudWxsfHVuZGVmaW5lZH0gc2NvcGVcbiAqL1xuYXN5bmMucnVuLldvcmtJdGVtXyA9IGZ1bmN0aW9uKGZuLCBzY29wZSkge1xuXHQvKiogQGNvbnN0ICovXG5cdHRoaXMuZm4gPSBmbjtcblx0LyoqIEBjb25zdCAqL1xuXHR0aGlzLnNjb3BlID0gc2NvcGU7XG59O1xuXG4vKipcbiAqIEZpcmVzIHRoZSBwcm92aWRlZCBjYWxsYmFja3MgYXMgc29vbiBhcyBwb3NzaWJsZSBhZnRlciB0aGUgY3VycmVudCBKU1xuICogZXhlY3V0aW9uIGNvbnRleHQuIHNldFRpbWVvdXQo4oCmLCAwKSBhbHdheXMgdGFrZXMgYXQgbGVhc3QgNW1zIGZvciBsZWdhY3lcbiAqIHJlYXNvbnMuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6U0NPUEUpfSBjYWxsYmFjayBDYWxsYmFjayBmdW5jdGlvbiB0byBmaXJlIGFzIHNvb24gYXNcbiAqICAgICBwb3NzaWJsZS5cbiAqIEBwYXJhbSB7U0NPUEU9fSBjb250ZXh0IE9iamVjdCBpbiB3aG9zZSBzY29wZSB0byBjYWxsIHRoZSBsaXN0ZW5lci5cbiAqIEB0ZW1wbGF0ZSBTQ09QRVxuICovXG5hc3luYy5uZXh0VGljayA9IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG5cdGxldCBjYiA9IGNhbGxiYWNrO1xuXHRpZiAoY29udGV4dCkge1xuXHRcdGNiID0gY2FsbGJhY2suYmluZChjb250ZXh0KTtcblx0fVxuXHRjYiA9IGFzeW5jLm5leHRUaWNrLndyYXBDYWxsYmFja18oY2IpO1xuXHQvLyBMb29rIGZvciBhbmQgY2FjaGUgdGhlIGN1c3RvbSBmYWxsYmFjayB2ZXJzaW9uIG9mIHNldEltbWVkaWF0ZS5cblx0aWYgKCFhc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfKSB7XG5cdFx0aWYgKFxuXHRcdFx0dHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdFx0aXNTZXJ2ZXJTaWRlKHtjaGVja0VudjogZmFsc2V9KVxuXHRcdCkge1xuXHRcdFx0YXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyA9IHNldEltbWVkaWF0ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cdFx0XHRhc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfID0gYXN5bmMubmV4dFRpY2suZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfKCk7XG5cdFx0fVxuXHR9XG5cdGFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8oY2IpO1xufTtcblxuLyoqXG4gKiBDYWNoZSBmb3IgdGhlIHNldEltbWVkaWF0ZSBpbXBsZW1lbnRhdGlvbi5cbiAqIEB0eXBlIHtmdW5jdGlvbihmdW5jdGlvbigpKX1cbiAqIEBwcml2YXRlXG4gKi9cbmFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8gPSBudWxsO1xuXG4vKipcbiAqIERldGVybWluZXMgdGhlIGJlc3QgcG9zc2libGUgaW1wbGVtZW50YXRpb24gdG8gcnVuIGEgZnVuY3Rpb24gYXMgc29vbiBhc1xuICogdGhlIEpTIGV2ZW50IGxvb3AgaXMgaWRsZS5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGZ1bmN0aW9uKCkpfSBUaGUgXCJzZXRJbW1lZGlhdGVcIiBpbXBsZW1lbnRhdGlvbi5cbiAqIEBwcml2YXRlXG4gKi9cbmFzeW5jLm5leHRUaWNrLmdldFNldEltbWVkaWF0ZUVtdWxhdG9yXyA9IGZ1bmN0aW9uKCkge1xuXHQvLyBDcmVhdGUgYSBwcml2YXRlIG1lc3NhZ2UgY2hhbm5lbCBhbmQgdXNlIGl0IHRvIHBvc3RNZXNzYWdlIGVtcHR5IG1lc3NhZ2VzXG5cdC8vIHRvIG91cnNlbHZlcy5cblx0bGV0IENoYW5uZWw7XG5cblx0Ly8gVmVyaWZ5IGlmIHZhcmlhYmxlIGlzIGRlZmluZWQgb24gdGhlIGN1cnJlbnQgcnVudGltZSAoaS5lLiwgbm9kZSwgYnJvd3NlcikuXG5cdC8vIENhbid0IHVzZSB0eXBlb2YgZW5jbG9zZWQgaW4gYSBmdW5jdGlvbiAoc3VjaCBhcyBjb3JlLmlzRnVuY3Rpb24pIG9yIGFuXG5cdC8vIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93biB3aGVuIHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgb24gYW4gZW52aXJvbm1lbnRcblx0Ly8gd2hlcmUgdGhlIHZhcmlhYmxlIGlzIHVuZGVmaW5lZC5cblx0aWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdENoYW5uZWwgPSBNZXNzYWdlQ2hhbm5lbDtcblx0fVxuXG5cdC8vIElmIE1lc3NhZ2VDaGFubmVsIGlzIG5vdCBhdmFpbGFibGUgYW5kIHdlIGFyZSBpbiBhIGJyb3dzZXIsIGltcGxlbWVudFxuXHQvLyBhbiBpZnJhbWUgYmFzZWQgcG9seWZpbGwgaW4gYnJvd3NlcnMgdGhhdCBoYXZlIHBvc3RNZXNzYWdlIGFuZFxuXHQvLyBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyLiBUaGUgbGF0dGVyIGV4Y2x1ZGVzIElFOCBiZWNhdXNlIGl0IGhhcyBhXG5cdC8vIHN5bmNocm9ub3VzIHBvc3RNZXNzYWdlIGltcGxlbWVudGF0aW9uLlxuXHRpZiAoXG5cdFx0dHlwZW9mIENoYW5uZWwgPT09ICd1bmRlZmluZWQnICYmXG5cdFx0dHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR3aW5kb3cucG9zdE1lc3NhZ2UgJiZcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuXHQpIHtcblx0XHQvKiogQGNvbnN0cnVjdG9yICovXG5cdFx0Q2hhbm5lbCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gTWFrZSBhbiBlbXB0eSwgaW52aXNpYmxlIGlmcmFtZS5cblx0XHRcdGNvbnN0IGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuXHRcdFx0aWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0XHRpZnJhbWUuc3JjID0gJyc7XG5cdFx0XHRpZnJhbWUudGl0bGUgPSAnJztcblx0XHRcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChpZnJhbWUpO1xuXHRcdFx0Y29uc3Qgd2luID0gaWZyYW1lLmNvbnRlbnRXaW5kb3c7XG5cdFx0XHRjb25zdCBkb2MgPSB3aW4uZG9jdW1lbnQ7XG5cdFx0XHRkb2Mub3BlbigpO1xuXHRcdFx0ZG9jLndyaXRlKCcnKTtcblx0XHRcdGRvYy5jbG9zZSgpO1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9ICdjYWxsSW1tZWRpYXRlJyArIE1hdGgucmFuZG9tKCk7XG5cdFx0XHRjb25zdCBvcmlnaW4gPSB3aW4ubG9jYXRpb24ucHJvdG9jb2wgKyAnLy8nICsgd2luLmxvY2F0aW9uLmhvc3Q7XG5cdFx0XHRjb25zdCBvbm1lc3NhZ2UgPSBmdW5jdGlvbihlKSB7XG5cdFx0XHRcdC8vIFZhbGlkYXRlIG9yaWdpbiBhbmQgbWVzc2FnZSB0byBtYWtlIHN1cmUgdGhhdCB0aGlzIG1lc3NhZ2Ugd2FzXG5cdFx0XHRcdC8vIGludGVuZGVkIGZvciB1cy5cblx0XHRcdFx0aWYgKGUub3JpZ2luICE9PSBvcmlnaW4gJiYgZS5kYXRhICE9PSBtZXNzYWdlKSB7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMucG9ydDEub25tZXNzYWdlKCk7XG5cdFx0XHR9LmJpbmQodGhpcyk7XG5cdFx0XHR3aW4uYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9ubWVzc2FnZSwgZmFsc2UpO1xuXHRcdFx0dGhpcy5wb3J0MSA9IHt9O1xuXHRcdFx0dGhpcy5wb3J0MiA9IHtcblx0XHRcdFx0cG9zdE1lc3NhZ2U6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHdpbi5wb3N0TWVzc2FnZShtZXNzYWdlLCBvcmlnaW4pO1xuXHRcdFx0XHR9LFxuXHRcdFx0fTtcblx0XHR9O1xuXHR9XG5cdGlmICh0eXBlb2YgQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRjb25zdCBjaGFubmVsID0gbmV3IENoYW5uZWwoKTtcblx0XHQvLyBVc2UgYSBmaWZvIGxpbmtlZCBsaXN0IHRvIGNhbGwgY2FsbGJhY2tzIGluIHRoZSByaWdodCBvcmRlci5cblx0XHRsZXQgaGVhZCA9IHt9O1xuXHRcdGxldCB0YWlsID0gaGVhZDtcblx0XHRjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aGVhZCA9IGhlYWQubmV4dDtcblx0XHRcdGNvbnN0IGNiID0gaGVhZC5jYjtcblx0XHRcdGhlYWQuY2IgPSBudWxsO1xuXHRcdFx0Y2IoKTtcblx0XHR9O1xuXHRcdHJldHVybiBmdW5jdGlvbihjYikge1xuXHRcdFx0dGFpbC5uZXh0ID0ge1xuXHRcdFx0XHRjYjogY2IsXG5cdFx0XHR9O1xuXHRcdFx0dGFpbCA9IHRhaWwubmV4dDtcblx0XHRcdGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG5cdFx0fTtcblx0fVxuXHQvLyBJbXBsZW1lbnRhdGlvbiBmb3IgSUU2LTg6IFNjcmlwdCBlbGVtZW50cyBmaXJlIGFuIGFzeW5jaHJvbm91c1xuXHQvLyBvbnJlYWR5c3RhdGVjaGFuZ2UgZXZlbnQgd2hlbiBpbnNlcnRlZCBpbnRvIHRoZSBET00uXG5cdGlmIChcblx0XHR0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmXG5cdFx0J29ucmVhZHlzdGF0ZWNoYW5nZScgaW4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jylcblx0KSB7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0XHRsZXQgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cdFx0XHRzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdC8vIENsZWFuIHVwIGFuZCBjYWxsIHRoZSBjYWxsYmFjay5cblx0XHRcdFx0c2NyaXB0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IG51bGw7XG5cdFx0XHRcdHNjcmlwdC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNjcmlwdCk7XG5cdFx0XHRcdHNjcmlwdCA9IG51bGw7XG5cdFx0XHRcdGNiKCk7XG5cdFx0XHRcdGNiID0gbnVsbDtcblx0XHRcdH07XG5cdFx0XHRkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcblx0XHR9O1xuXHR9XG5cdC8vIEZhbGwgYmFjayB0byBzZXRUaW1lb3V0IHdpdGggMC4gSW4gYnJvd3NlcnMgdGhpcyBjcmVhdGVzIGEgZGVsYXkgb2YgNW1zXG5cdC8vIG9yIG1vcmUuXG5cdHJldHVybiBmdW5jdGlvbihjYikge1xuXHRcdHNldFRpbWVvdXQoY2IsIDApO1xuXHR9O1xufTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBpcyBvdmVycmlkZWQgdG8gcHJvdGVjdCBjYWxsYmFja3Mgd2l0aCBlbnRyeSBwb2ludFxuICogbW9uaXRvciBpZiB0aGUgYXBwbGljYXRpb24gbW9uaXRvcnMgZW50cnkgcG9pbnRzLlxuICogQHBhcmFtIHtmdW5jdGlvbigpfSBjYWxsYmFjayBDYWxsYmFjayBmdW5jdGlvbiB0byBmaXJlIGFzIHNvb24gYXMgcG9zc2libGUuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbigpfSBUaGUgd3JhcHBlZCBjYWxsYmFjay5cbiAqIEBwcml2YXRlXG4gKi9cbmFzeW5jLm5leHRUaWNrLndyYXBDYWxsYmFja18gPSBmdW5jdGlvbihjYWxsYmFjaykge1xuXHRyZXR1cm4gY2FsbGJhY2s7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBhc3luYztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBEaXNwb3NhYmxlIHV0aWxpdHkuIFdoZW4gaW5oZXJpdGVkIHByb3ZpZGVzIHRoZSBgZGlzcG9zZWAgZnVuY3Rpb24gdG8gaXRzXG4gKiBzdWJjbGFzcywgd2hpY2ggaXMgcmVzcG9uc2libGUgZm9yIGRpc3Bvc2luZyBvZiBhbnkgb2JqZWN0IHJlZmVyZW5jZXNcbiAqIHdoZW4gYW4gaW5zdGFuY2Ugd29uJ3QgYmUgdXNlZCBhbnltb3JlLiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZVxuICogYGRpc3Bvc2VJbnRlcm5hbGAgdG8gaW1wbGVtZW50IGFueSBzcGVjaWZpYyBkaXNwb3NpbmcgbG9naWMuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuY2xhc3MgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBEaXNwb3NhYmxlIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHQvKipcblx0XHQgKiBGbGFnIGluZGljYXRpbmcgaWYgdGhpcyBpbnN0YW5jZSBoYXMgYWxyZWFkeSBiZWVuIGRpc3Bvc2VkLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmRpc3Bvc2VkXyA9IGZhbHNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy4gQ2FsbHMgYGRpc3Bvc2VJbnRlcm5hbGAuXG5cdCAqL1xuXHRkaXNwb3NlKCkge1xuXHRcdGlmICghdGhpcy5kaXNwb3NlZF8pIHtcblx0XHRcdHRoaXMuZGlzcG9zZUludGVybmFsKCk7XG5cdFx0XHR0aGlzLmRpc3Bvc2VkXyA9IHRydWU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIGltcGxlbWVudCBhbnkgc3BlY2lmaWNcblx0ICogZGlzcG9zaW5nIGxvZ2ljIChsaWtlIGNsZWFyaW5nIHJlZmVyZW5jZXMgYW5kIGNhbGxpbmcgYGRpc3Bvc2VgIG9uIG90aGVyXG5cdCAqIGRpc3Bvc2FibGVzKS5cblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHt9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGlzIGluc3RhbmNlIGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRpc0Rpc3Bvc2VkKCkge1xuXHRcdHJldHVybiB0aGlzLmRpc3Bvc2VkXztcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBEaXNwb3NhYmxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFNldCBvZiB1dGlsaXRpZXMgZm9yIG9iamVjdCBvcGVyYXRpb25zXG4gKi9cbmNsYXNzIG9iamVjdCB7XG5cdC8qKlxuXHQgKiBDb3BpZXMgYWxsIHRoZSBtZW1iZXJzIG9mIGEgc291cmNlIG9iamVjdCB0byBhIHRhcmdldCBvYmplY3QuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXQgVGFyZ2V0IG9iamVjdC5cblx0ICogQHBhcmFtIHsuLi5PYmplY3R9IHZhcl9hcmdzIFRoZSBvYmplY3RzIGZyb20gd2hpY2ggdmFsdWVzIHdpbGwgYmUgY29waWVkLlxuXHQgKiBAcmV0dXJuIHtPYmplY3R9IFJldHVybnMgdGhlIHRhcmdldCBvYmplY3QgcmVmZXJlbmNlLlxuXHQgKi9cblx0c3RhdGljIG1peGluKHRhcmdldCwgLi4uYXJncykge1xuXHRcdGxldCBrZXk7XG5cdFx0bGV0IHNvdXJjZTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdHNvdXJjZSA9IGFyZ3NbaV07XG5cdFx0XHQvLyBQb3NzaWJsZSBwcm90b3R5cGUgY2hhaW4gbGVhaywgYnJlYWtzIDEgbWV0YWwtZG9tIGFuZFxuXHRcdFx0Ly8gMSBtZXRhbC1pbmNyZW1lbnRhbC1kb20gdGVzdCBpZiBndWFyZC1mb3ItaW4gcnVsZSBpcyBhZGRyZXNzZWRcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXHRcdFx0Zm9yIChrZXkgaW4gc291cmNlKSB7XG5cdFx0XHRcdHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0YXJnZXQ7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhbiBvYmplY3QgYmFzZWQgb24gaXRzIGZ1bGx5IHF1YWxpZmllZCBleHRlcm5hbCBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUuXG5cdCAqIEBwYXJhbSB7b2JqZWN0PX0gc2NvcGUgVGhlIG9iamVjdCB3aXRoaW4gd2hpY2ggdG8gbG9vazsgZGVmYXVsdCBpc1xuXHQgKiAgICAgPGNvZGU+d2luZG93PC9jb2RlPi5cblx0ICogQHJldHVybiB7P30gVGhlIHZhbHVlIChvYmplY3Qgb3IgcHJpbWl0aXZlKSBvciwgaWYgbm90IGZvdW5kLCB1bmRlZmluZWQuXG5cdCAqL1xuXHRzdGF0aWMgZ2V0T2JqZWN0QnlOYW1lKG5hbWUsIHNjb3BlID0gd2luZG93KSB7XG5cdFx0Y29uc3QgcGFydHMgPSBuYW1lLnNwbGl0KCcuJyk7XG5cdFx0cmV0dXJuIHBhcnRzLnJlZHVjZSgocGFydCwga2V5KSA9PiBwYXJ0W2tleV0sIHNjb3BlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgbmV3IG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleXMgYXMgdGhlIGdpdmVuIG9uZSwgYnV0IHdpdGhcblx0ICogdGhlaXIgdmFsdWVzIHNldCB0byB0aGUgcmV0dXJuIHZhbHVlcyBvZiB0aGUgc3BlY2lmaWVkIGZ1bmN0aW9uLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IG9ialxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbihzdHJpbmcsICopfSBmblxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fVxuXHQgKi9cblx0c3RhdGljIG1hcChvYmosIGZuKSB7XG5cdFx0Y29uc3QgbWFwcGVkT2JqID0ge307XG5cdFx0Y29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRtYXBwZWRPYmpba2V5c1tpXV0gPSBmbihrZXlzW2ldLCBvYmpba2V5c1tpXV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gbWFwcGVkT2JqO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgdHdvIGdpdmVuIG9iamVjdHMgYXJlIGVxdWFsLiBUaGlzIGlzIGRvbmUgdmlhIGEgc2hhbGxvd1xuXHQgKiBjaGVjaywgaW5jbHVkaW5nIG9ubHkgdGhlIGtleXMgZGlyZWN0bHkgY29udGFpbmVkIGJ5IHRoZSAyIG9iamVjdHMuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmoxXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvYmoyXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRzdGF0aWMgc2hhbGxvd0VxdWFsKG9iajEsIG9iajIpIHtcblx0XHRpZiAob2JqMSA9PT0gb2JqMikge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Y29uc3Qga2V5czEgPSBPYmplY3Qua2V5cyhvYmoxKTtcblx0XHRjb25zdCBrZXlzMiA9IE9iamVjdC5rZXlzKG9iajIpO1xuXHRcdGlmIChrZXlzMS5sZW5ndGggIT09IGtleXMyLmxlbmd0aCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwga2V5czEubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChvYmoxW2tleXMxW2ldXSAhPT0gb2JqMltrZXlzMVtpXV0pIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBvYmplY3Q7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3Igc3RyaW5nIG9wZXJhdGlvbnNcbiAqL1xuY2xhc3Mgc3RyaW5nIHtcblx0LyoqXG5cdCAqIENvbXBhcmVzIHRoZSBnaXZlbiBzdHJpbmdzIHdpdGhvdXQgdGFraW5nIHRoZSBjYXNlIGludG8gYWNjb3VudC5cblx0ICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdHIxXG5cdCAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gc3RyMlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9IEVpdGhlciAtMSwgMCBvciAxLCBhY2NvcmRpbmcgdG8gaWYgdGhlIGZpcnN0IHN0cmluZyBpc1xuXHQgKiAgICAgXCJzbWFsbGVyXCIsIGVxdWFsIG9yIFwiYmlnZ2VyXCIgdGhhbiB0aGUgc2Vjb25kIGdpdmVuIHN0cmluZy5cblx0ICovXG5cdHN0YXRpYyBjYXNlSW5zZW5zaXRpdmVDb21wYXJlKHN0cjEsIHN0cjIpIHtcblx0XHRjb25zdCB0ZXN0MSA9IFN0cmluZyhzdHIxKS50b0xvd2VyQ2FzZSgpO1xuXHRcdGNvbnN0IHRlc3QyID0gU3RyaW5nKHN0cjIpLnRvTG93ZXJDYXNlKCk7XG5cblx0XHRpZiAodGVzdDEgPCB0ZXN0Mikge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH0gZWxzZSBpZiAodGVzdDEgPT09IHRlc3QyKSB7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGJyZWFraW5nIHNwYWNlcyBmcm9tIHRoZSBsZWZ0IGFuZCByaWdodCBvZiB0aGUgc3RyaW5nIGFuZFxuXHQgKiBjb2xsYXBzZXMgdGhlIHNlcXVlbmNlcyBvZiBicmVha2luZyBzcGFjZXMgaW4gdGhlIG1pZGRsZSBpbnRvIHNpbmdsZSBzcGFjZXMuXG5cdCAqIFRoZSBvcmlnaW5hbCBhbmQgdGhlIHJlc3VsdCBzdHJpbmdzIHJlbmRlciB0aGUgc2FtZSB3YXkgaW4gSFRNTC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0ciBBIHN0cmluZyBpbiB3aGljaCB0byBjb2xsYXBzZSBzcGFjZXMuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQ29weSBvZiB0aGUgc3RyaW5nIHdpdGggbm9ybWFsaXplZCBicmVha2luZyBzcGFjZXMuXG5cdCAqL1xuXHRzdGF0aWMgY29sbGFwc2VCcmVha2luZ1NwYWNlcyhzdHIpIHtcblx0XHRyZXR1cm4gc3RyXG5cdFx0XHQucmVwbGFjZSgvW1xcdFxcclxcbiBdKy9nLCAnICcpXG5cdFx0XHQucmVwbGFjZSgvXltcXHRcXHJcXG4gXSt8W1xcdFxcclxcbiBdKyQvZywgJycpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEVzY2FwZXMgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nIHRoYXQgYXJlIG5vdCBzYWZlIHRvIHVzZSBpbiBhIFJlZ0V4cC5cblx0ICogQHBhcmFtIHsqfSBzdHIgVGhlIHN0cmluZyB0byBlc2NhcGUuIElmIG5vdCBhIHN0cmluZywgaXQgd2lsbCBiZSBjYXN0ZWRcblx0ICogICAgIHRvIG9uZS5cblx0ICogQHJldHVybiB7c3RyaW5nfSBBIFJlZ0V4cCBzYWZlLCBlc2NhcGVkIGNvcHkgb2Yge0Bjb2RlIHN9LlxuXHQgKi9cblx0c3RhdGljIGVzY2FwZVJlZ2V4KHN0cikge1xuXHRcdHJldHVybiBTdHJpbmcoc3RyKVxuXHRcdFx0LnJlcGxhY2UoLyhbLSgpW1xcXXt9Kz8qLiRefCw6IzwhXFxcXF0pL2csICdcXFxcJDEnKVxuXHRcdFx0LnJlcGxhY2UoL1xceDA4L2csICdcXFxceDA4Jyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgc3RyaW5nIHdpdGggYXQgbGVhc3QgNjQtYml0cyBvZiByYW5kb21uZXNzLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEEgcmFuZG9tIHN0cmluZywgZS5nLiBzbjFzN3ZiNGdjaWMuXG5cdCAqL1xuXHRzdGF0aWMgZ2V0UmFuZG9tU3RyaW5nKCkge1xuXHRcdGNvbnN0IHggPSAyMTQ3NDgzNjQ4O1xuXHRcdHJldHVybiAoXG5cdFx0XHRNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB4KS50b1N0cmluZygzNikgK1xuXHRcdFx0TWF0aC5hYnMoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogeCkgXiBEYXRlLm5vdygpKS50b1N0cmluZygzNilcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENhbGN1bGF0ZXMgdGhlIGhhc2hjb2RlIGZvciBhIHN0cmluZy4gVGhlIGhhc2hjb2RlIHZhbHVlIGlzIGNvbXB1dGVkIGJ5XG5cdCAqIHRoZSBzdW0gYWxnb3JpdGhtOiBzWzBdKjMxXihuLTEpICsgc1sxXSozMV4obi0yKSArIC4uLiArIHNbbi0xXS4gQSBuaWNlXG5cdCAqIHByb3BlcnR5IG9mIHVzaW5nIDMxIHByaW1lIGlzIHRoYXQgdGhlIG11bHRpcGxpY2F0aW9uIGNhbiBiZSByZXBsYWNlZCBieVxuXHQgKiBhIHNoaWZ0IGFuZCBhIHN1YnRyYWN0aW9uIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2U6IDMxKmkgPT0gKGk8PDUpLWkuXG5cdCAqIE1vZGVybiBWTXMgZG8gdGhpcyBzb3J0IG9mIG9wdGltaXphdGlvbiBhdXRvbWF0aWNhbGx5LlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gdmFsIFRhcmdldCBzdHJpbmcuXG5cdCAqIEByZXR1cm4ge051bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIGhhc2hjb2RlLlxuXHQgKi9cblx0c3RhdGljIGhhc2hDb2RlKHZhbCkge1xuXHRcdGxldCBoYXNoID0gMDtcblx0XHRmb3IgKGxldCBpID0gMCwgbGVuID0gdmFsLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRoYXNoID0gMzEgKiBoYXNoICsgdmFsLmNoYXJDb2RlQXQoaSk7XG5cdFx0XHRoYXNoICU9IDB4MTAwMDAwMDAwO1xuXHRcdH1cblx0XHRyZXR1cm4gaGFzaDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXBsYWNlcyBpbnRlcnZhbCBpbnRvIHRoZSBzdHJpbmcgd2l0aCBzcGVjaWZpZWQgdmFsdWUsIGUuZy5cblx0ICogYHJlcGxhY2VJbnRlcnZhbChcImFiY2RlXCIsIDEsIDQsIFwiXCIpYCByZXR1cm5zIFwiYWVcIi5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0ciBUaGUgaW5wdXQgc3RyaW5nLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gc3RhcnQgU3RhcnQgaW50ZXJ2YWwgcG9zaXRpb24gdG8gYmUgcmVwbGFjZWQuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBlbmQgRW5kIGludGVydmFsIHBvc2l0aW9uIHRvIGJlIHJlcGxhY2VkLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgVGhlIHZhbHVlIHRoYXQgcmVwbGFjZXMgdGhlIHNwZWNpZmllZCBpbnRlcnZhbC5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0c3RhdGljIHJlcGxhY2VJbnRlcnZhbChzdHIsIHN0YXJ0LCBlbmQsIHZhbHVlKSB7XG5cdFx0cmV0dXJuIHN0ci5zdWJzdHJpbmcoMCwgc3RhcnQpICsgdmFsdWUgKyBzdHIuc3Vic3RyaW5nKGVuZCk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgc3RyaW5nO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2lzRGVmfSBmcm9tICdtZXRhbCc7XG5cbmNvbnN0IE1FVEFMX0RBVEEgPSAnX19tZXRhbF9kYXRhX18nO1xuXG4vKipcbiAqIFNldCBvZiB1dGlsaXRpZXMgZm9yIGRvbSBkYXRhIG9wZXJhdGlvbnNcbiAqL1xuY2xhc3MgZG9tRGF0YSB7XG5cdC8qKlxuXHQgKiBHZXRzIE1ldGFsLmpzJ3MgZGF0YSBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHBhcmFtIHtzdHJpbmc9fSBuYW1lIE9wdGlvbmFsIHByb3BlcnR5IGZyb20gdGhlIGRhdGEgdG8gYmUgcmV0dXJuZWQuXG5cdCAqIEBwYXJhbSB7Kj19IGluaXRpYWxWYWx1ZSBPcHRpb25hbCB2YWx1ZSB0byB0aGUgc2V0IHRoZSByZXF1ZXN0ZWQgcHJvcGVydHlcblx0ICogICAgIHRvIGlmIGl0IGRvZXNuJ3QgZXhpc3QgeWV0IGluIHRoZSBkYXRhLlxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fVxuXHQgKi9cblx0c3RhdGljIGdldChlbGVtZW50LCBuYW1lLCBpbml0aWFsVmFsdWUpIHtcblx0XHRpZiAoIWVsZW1lbnRbTUVUQUxfREFUQV0pIHtcblx0XHRcdGVsZW1lbnRbTUVUQUxfREFUQV0gPSB7fTtcblx0XHR9XG5cdFx0aWYgKCFuYW1lKSB7XG5cdFx0XHRyZXR1cm4gZWxlbWVudFtNRVRBTF9EQVRBXTtcblx0XHR9XG5cdFx0aWYgKCFpc0RlZihlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdKSAmJiBpc0RlZihpbml0aWFsVmFsdWUpKSB7XG5cdFx0XHRlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdID0gaW5pdGlhbFZhbHVlO1xuXHRcdH1cblx0XHRyZXR1cm4gZWxlbWVudFtNRVRBTF9EQVRBXVtuYW1lXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaGFzIGRhdGEgc3RvcmVkIGluIGl0LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRzdGF0aWMgaGFzKGVsZW1lbnQpIHtcblx0XHRyZXR1cm4gISFlbGVtZW50W01FVEFMX0RBVEFdO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgTWV0YWwuanMncyBkYXRhIGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuXHQgKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgUHJvcGVydHkgZnJvbSB0aGUgZGF0YSB0byBiZSBzZXQuXG5cdCAqIEBwYXJhbSB7Kj19IHZhbHVlIFZhbHVlIHRvIGJlIHNldCBvbiB0aGUgZWxlbWVudC5cblx0ICogQHJldHVybiB7IU9iamVjdHwqfVxuXHQgKi9cblx0c3RhdGljIHNldChlbGVtZW50LCBuYW1lLCB2YWx1ZSkge1xuXHRcdGlmICghZWxlbWVudFtNRVRBTF9EQVRBXSkge1xuXHRcdFx0ZWxlbWVudFtNRVRBTF9EQVRBXSA9IHt9O1xuXHRcdH1cblx0XHRpZiAoIW5hbWUgfHwgIWlzRGVmKHZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIGVsZW1lbnRbTUVUQUxfREFUQV07XG5cdFx0fVxuXHRcdGVsZW1lbnRbTUVUQUxfREFUQV1bbmFtZV0gPSB2YWx1ZTtcblx0XHRyZXR1cm4gZWxlbWVudFtNRVRBTF9EQVRBXVtuYW1lXTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBkb21EYXRhO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge0Rpc3Bvc2FibGV9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBFdmVudEhhbmRsZSB1dGlsaXR5LiBIb2xkcyBpbmZvcm1hdGlvbiBhYm91dCBhbiBldmVudCBzdWJzY3JpcHRpb24sIGFuZFxuICogYWxsb3dzIHJlbW92aW5nIHRoZW0gZWFzaWx5LlxuICogRXZlbnRIYW5kbGUgaXMgYSBEaXNwb3NhYmxlLCBidXQgaXQncyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IHRoZVxuICogRXZlbnRFbWl0dGVyIHRoYXQgY3JlYXRlZCBpdCBpcyBub3QgdGhlIG9uZSByZXNwb25zaWJsZSBmb3IgZGlzcG9zaW5nIGl0LlxuICogVGhhdCByZXNwb25zaWJpbGl0eSBpcyBmb3IgdGhlIGNvZGUgdGhhdCBob2xkcyBhIHJlZmVyZW5jZSB0byBpdC5cbiAqIEBleHRlbmRzIHtEaXNwb3NhYmxlfVxuICovXG5jbGFzcyBFdmVudEhhbmRsZSBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRIYW5kbGUgY29uc3RydWN0b3Jcblx0ICogQHBhcmFtIHshRXZlbnRFbWl0dGVyfSBlbWl0dGVyIEVtaXR0ZXIgdGhlIGV2ZW50IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnQgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRoYXQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgc3Vic2NyaWJlZCB0byB0aGUgZXZlbnQuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIEV2ZW50RW1pdHRlciBpbnN0YW5jZSB0aGF0IHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0XHQgKiBAdHlwZSB7RXZlbnRFbWl0dGVyfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmVtaXR0ZXJfID0gZW1pdHRlcjtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZXZlbnRfID0gZXZlbnQ7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgbGlzdGVuZXIgc3Vic2NyaWJlZCB0byB0aGUgZXZlbnQuXG5cdFx0ICogQHR5cGUge0Z1bmN0aW9ufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmxpc3RlbmVyXyA9IGxpc3RlbmVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdHRoaXMuZW1pdHRlcl8gPSBudWxsO1xuXHRcdHRoaXMubGlzdGVuZXJfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBzdWJzY3JpcHRpb24gZnJvbSB0aGUgZW1pdHRlci5cblx0ICovXG5cdHJlbW92ZUxpc3RlbmVyKCkge1xuXHRcdGlmICghdGhpcy5lbWl0dGVyXy5pc0Rpc3Bvc2VkKCkpIHtcblx0XHRcdHRoaXMuZW1pdHRlcl8ucmVtb3ZlTGlzdGVuZXIodGhpcy5ldmVudF8sIHRoaXMubGlzdGVuZXJfKTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRIYW5kbGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXJyYXksIERpc3Bvc2FibGUsIGlzRnVuY3Rpb24sIGlzU3RyaW5nfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgRXZlbnRIYW5kbGUgZnJvbSAnLi9FdmVudEhhbmRsZSc7XG5cbmNvbnN0IHNpbmdsZUFycmF5XyA9IFswXTtcblxuLyoqXG4gKiBFdmVudEVtaXR0ZXIgdXRpbGl0eS5cbiAqIEBleHRlbmRzIHtEaXNwb3NhYmxlfVxuICovXG5jbGFzcyBFdmVudEVtaXR0ZXIgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIEV2ZW50RW1pdHRlciBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGV2ZW50IGxpc3RlbmVycyBzY29wZWQgYnkgZXZlbnQgdHlwZS5cblx0XHQgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgIUFycmF5PCFmdW5jdGlvbigpPj59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZXZlbnRzXyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIYW5kbGVycyB0aGF0IGFyZSB0cmlnZ2VyZWQgd2hlbiBhbiBldmVudCBpcyBsaXN0ZW5lZCB0by5cblx0XHQgKiBAdHlwZSB7QXJyYXl9XG5cdFx0ICovXG5cdFx0dGhpcy5saXN0ZW5lckhhbmRsZXJzXyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBDb25maWd1cmF0aW9uIG9wdGlvbiB3aGljaCBkZXRlcm1pbmVzIGlmIGFuIGV2ZW50IGZhY2FkZSBzaG91bGQgYmUgc2VudFxuXHRcdCAqIGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGZhY2FkZVxuXHRcdCAqIHdpbGwgYmUgcGFzc2VkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCBvZiB0aGUgbGlzdGVuZXIuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuc2hvdWxkVXNlRmFjYWRlXyA9IGZhbHNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBoYW5kbGVyIHRvIGdpdmVuIGhvbGRlciB2YXJpYWJsZS4gSWYgdGhlIGhvbGRlciBkb2Vzbid0IGhhdmUgYVxuXHQgKiB2YWx1ZSB5ZXQsIGl0IHdpbGwgcmVjZWl2ZSB0aGUgaGFuZGxlciBkaXJlY3RseS4gSWYgdGhlIGhvbGRlciBpcyBhbiBhcnJheSxcblx0ICogdGhlIHZhbHVlIHdpbGwganVzdCBiZSBhZGRlZCB0byBpdC4gT3RoZXJ3aXNlLCB0aGUgaG9sZGVyIHdpbGwgYmUgc2V0IHRvIGFcblx0ICogbmV3IGFycmF5IGNvbnRhaW5pbmcgaXRzIHByZXZpb3VzIHZhbHVlIHBsdXMgdGhlIG5ldyBoYW5kbGVyLlxuXHQgKiBAcGFyYW0geyp9IGhvbGRlclxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfE9iamVjdH0gaGFuZGxlclxuXHQgKiBAcmV0dXJuIHsqfSBUaGUgaG9sZGVyJ3MgbmV3IHZhbHVlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRhZGRIYW5kbGVyXyhob2xkZXIsIGhhbmRsZXIpIHtcblx0XHRpZiAoIWhvbGRlcikge1xuXHRcdFx0aG9sZGVyID0gaGFuZGxlcjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKCFBcnJheS5pc0FycmF5KGhvbGRlcikpIHtcblx0XHRcdFx0aG9sZGVyID0gW2hvbGRlcl07XG5cdFx0XHR9XG5cdFx0XHRob2xkZXIucHVzaChoYW5kbGVyKTtcblx0XHR9XG5cdFx0cmV0dXJuIGhvbGRlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50cy5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50XG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGRlZmF1bHRMaXN0ZW5lciBGbGFnIGluZGljYXRpbmcgaWYgdGhpcyBsaXN0ZW5lciBpcyBhIGRlZmF1bHRcblx0ICogICBhY3Rpb24gZm9yIHRoaXMgZXZlbnQuIERlZmF1bHQgYWN0aW9ucyBhcmUgcnVuIGxhc3QsIGFuZCBvbmx5IGlmIG5vIHByZXZpb3VzXG5cdCAqICAgbGlzdGVuZXIgY2FsbCBgcHJldmVudERlZmF1bHQoKWAgb24gdGhlIHJlY2VpdmVkIGV2ZW50IGZhY2FkZS5cblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0YWRkTGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyLCBkZWZhdWx0TGlzdGVuZXIpIHtcblx0XHR0aGlzLnZhbGlkYXRlTGlzdGVuZXJfKGxpc3RlbmVyKTtcblxuXHRcdGNvbnN0IGV2ZW50cyA9IHRoaXMudG9FdmVudHNBcnJheV8oZXZlbnQpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmFkZFNpbmdsZUxpc3RlbmVyXyhldmVudHNbaV0sIGxpc3RlbmVyLCBkZWZhdWx0TGlzdGVuZXIpO1xuXHRcdH1cblxuXHRcdHJldHVybiBuZXcgRXZlbnRIYW5kbGUodGhpcywgZXZlbnQsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciBhIHNpbmdsZSBldmVudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGRlZmF1bHRMaXN0ZW5lciBGbGFnIGluZGljYXRpbmcgaWYgdGhpcyBsaXN0ZW5lciBpcyBhIGRlZmF1bHRcblx0ICogICBhY3Rpb24gZm9yIHRoaXMgZXZlbnQuIERlZmF1bHQgYWN0aW9ucyBhcmUgcnVuIGxhc3QsIGFuZCBvbmx5IGlmIG5vIHByZXZpb3VzXG5cdCAqICAgbGlzdGVuZXIgY2FsbCBgcHJldmVudERlZmF1bHQoKWAgb24gdGhlIHJlY2VpdmVkIGV2ZW50IGZhY2FkZS5cblx0ICogQHBhcmFtIHtGdW5jdGlvbj19IG9yaWdpbiBUaGUgb3JpZ2luYWwgZnVuY3Rpb24gdGhhdCB3YXMgYWRkZWQgYXMgYVxuXHQgKiAgIGxpc3RlbmVyLCBpZiB0aGVyZSBpcyBhbnkuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGFkZFNpbmdsZUxpc3RlbmVyXyhldmVudCwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lciwgb3JpZ2luKSB7XG5cdFx0dGhpcy5ydW5MaXN0ZW5lckhhbmRsZXJzXyhldmVudCk7XG5cdFx0aWYgKGRlZmF1bHRMaXN0ZW5lciB8fCBvcmlnaW4pIHtcblx0XHRcdGxpc3RlbmVyID0ge1xuXHRcdFx0XHRkZWZhdWx0OiBkZWZhdWx0TGlzdGVuZXIsXG5cdFx0XHRcdGZuOiBsaXN0ZW5lcixcblx0XHRcdFx0b3JpZ2luOiBvcmlnaW4sXG5cdFx0XHR9O1xuXHRcdH1cblx0XHR0aGlzLmV2ZW50c18gPSB0aGlzLmV2ZW50c18gfHwge307XG5cdFx0dGhpcy5ldmVudHNfW2V2ZW50XSA9IHRoaXMuYWRkSGFuZGxlcl8odGhpcy5ldmVudHNfW2V2ZW50XSwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEJ1aWxkcyBmYWNhZGUgZm9yIHRoZSBnaXZlbiBldmVudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge09iamVjdH1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YnVpbGRGYWNhZGVfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuZ2V0U2hvdWxkVXNlRmFjYWRlKCkpIHtcblx0XHRcdGNvbnN0IGZhY2FkZSA9IHtcblx0XHRcdFx0cHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGZhY2FkZS5wcmV2ZW50ZWREZWZhdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSxcblx0XHRcdFx0dGFyZ2V0OiB0aGlzLFxuXHRcdFx0XHR0eXBlOiBldmVudCxcblx0XHRcdH07XG5cdFx0XHRyZXR1cm4gZmFjYWRlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBvZiB0aGlzIGluc3RhbmNlJ3Mgb2JqZWN0IHJlZmVyZW5jZXMuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMuZXZlbnRzXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogRXhlY3V0ZSBlYWNoIG9mIHRoZSBsaXN0ZW5lcnMgaW4gb3JkZXIgd2l0aCB0aGUgc3VwcGxpZWQgYXJndW1lbnRzLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHsqfSBvcHRfYXJncyBbYXJnMV0sIFthcmcyXSwgWy4uLl1cblx0ICogQHJldHVybiB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIGV2ZW50IGhhZCBsaXN0ZW5lcnMsIGZhbHNlIG90aGVyd2lzZS5cblx0ICovXG5cdGVtaXQoZXZlbnQpIHtcblx0XHRjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLmdldFJhd0xpc3RlbmVyc18oZXZlbnQpO1xuXHRcdGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Y29uc3QgYXJncyA9IGFycmF5LnNsaWNlKGFyZ3VtZW50cywgMSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHR0aGlzLnJ1bkxpc3RlbmVyc18obGlzdGVuZXJzLCBhcmdzLCB0aGlzLmJ1aWxkRmFjYWRlXyhldmVudCkpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGxpc3RlbmVyIG9iamVjdHMgZm9yIHRoZSBnaXZlbiBldmVudCwgaWYgdGhlcmUgYXJlIGFueS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4geyFBcnJheX1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0Z2V0UmF3TGlzdGVuZXJzXyhldmVudCkge1xuXHRcdGNvbnN0IGRpcmVjdExpc3RlbmVycyA9IHRvQXJyYXkodGhpcy5ldmVudHNfICYmIHRoaXMuZXZlbnRzX1tldmVudF0pO1xuXHRcdHJldHVybiBkaXJlY3RMaXN0ZW5lcnMuY29uY2F0KFxuXHRcdFx0dG9BcnJheSh0aGlzLmV2ZW50c18gJiYgdGhpcy5ldmVudHNfWycqJ10pXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBjb25maWd1cmF0aW9uIG9wdGlvbiB3aGljaCBkZXRlcm1pbmVzIGlmIGFuIGV2ZW50IGZhY2FkZSBzaG91bGRcblx0ICogYmUgc2VudCBhcyBhIHBhcmFtIG9mIGxpc3RlbmVycyB3aGVuIGVtaXR0aW5nIGV2ZW50cy4gSWYgc2V0IHRvIHRydWUsIHRoZVxuXHQgKiBmYWNhZGUgd2lsbCBiZSBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoZSBsaXN0ZW5lci5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGdldFNob3VsZFVzZUZhY2FkZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5zaG91bGRVc2VGYWNhZGVfO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7QXJyYXl9IEFycmF5IG9mIGxpc3RlbmVycy5cblx0ICovXG5cdGxpc3RlbmVycyhldmVudCkge1xuXHRcdHJldHVybiB0aGlzLmdldFJhd0xpc3RlbmVyc18oZXZlbnQpLm1hcChcblx0XHRcdGxpc3RlbmVyID0+IChsaXN0ZW5lci5mbiA/IGxpc3RlbmVyLmZuIDogbGlzdGVuZXIpXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgYSBmaXhlZCBudW1iZXIgb2YgdGltZXMgZm9yIHRoZVxuXHQgKiBldmVudHMuIEFmdGVyIGVhY2ggZXZlbnQgaXMgdHJpZ2dlcmVkIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWVzLCB0aGVcblx0ICogbGlzdGVuZXIgaXMgcmVtb3ZlZCBmb3IgaXQuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudFxuXHQgKiBAcGFyYW0ge251bWJlcn0gYW1vdW50IFRoZSBhbW91bnQgb2YgdGltZXMgdGhpcyBldmVudCBzaG91bGQgYmUgbGlzdGVuZWRcblx0ICogdG8uXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG5cdCAqL1xuXHRtYW55KGV2ZW50LCBhbW91bnQsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMubWFueV8oZXZlbnRzW2ldLCBhbW91bnQsIGxpc3RlbmVyKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbmV3IEV2ZW50SGFuZGxlKHRoaXMsIGV2ZW50LCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgZml4ZWQgbnVtYmVyIG9mIHRpbWVzIGZvciBhIHNpbmdsZVxuXHQgKiBldmVudC4gQWZ0ZXIgdGhlIGV2ZW50IGlzIHRyaWdnZXJlZCB0aGUgc3BlY2lmaWVkIGFtb3VudCBvZiB0aW1lcywgdGhlXG5cdCAqIGxpc3RlbmVyIGlzIHJlbW92ZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0ge251bWJlcn0gYW1vdW50IFRoZSBhbW91bnQgb2YgdGltZXMgdGhpcyBldmVudCBzaG91bGQgYmUgbGlzdGVuZWRcblx0ICogdG8uXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYW55XyhldmVudCwgYW1vdW50LCBsaXN0ZW5lcikge1xuXHRcdGNvbnN0IHNlbGYgPSB0aGlzO1xuXG5cdFx0aWYgKGFtb3VudCA8PSAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICpcblx0XHQgKi9cblx0XHRmdW5jdGlvbiBoYW5kbGVySW50ZXJuYWwoKSB7XG5cdFx0XHRpZiAoLS1hbW91bnQgPT09IDApIHtcblx0XHRcdFx0c2VsZi5yZW1vdmVMaXN0ZW5lcihldmVudCwgaGFuZGxlckludGVybmFsKTtcblx0XHRcdH1cblx0XHRcdGxpc3RlbmVyLmFwcGx5KHNlbGYsIGFyZ3VtZW50cyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHR9XG5cblx0XHRzZWxmLmFkZFNpbmdsZUxpc3RlbmVyXyhldmVudCwgaGFuZGxlckludGVybmFsLCBmYWxzZSwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBhIGxpc3RlbmVyIG9iamVjdCBtYXRjaGVzIHRoZSBnaXZlbiBsaXN0ZW5lciBmdW5jdGlvbi4gVG8gbWF0Y2gsXG5cdCAqIGl0IG5lZWRzIHRvIGVpdGhlciBwb2ludCB0byB0aGF0IGxpc3RlbmVyIG9yIGhhdmUgaXQgYXMgaXRzIG9yaWdpbi5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBsaXN0ZW5lck9ialxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0bWF0Y2hlc0xpc3RlbmVyXyhsaXN0ZW5lck9iaiwgbGlzdGVuZXIpIHtcblx0XHRjb25zdCBmbiA9IGxpc3RlbmVyT2JqLmZuIHx8IGxpc3RlbmVyT2JqO1xuXHRcdHJldHVybiAoXG5cdFx0XHRmbiA9PT0gbGlzdGVuZXIgfHxcblx0XHRcdChsaXN0ZW5lck9iai5vcmlnaW4gJiYgbGlzdGVuZXJPYmoub3JpZ2luID09PSBsaXN0ZW5lcikgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50cy5cblx0ICogQ2F1dGlvbjogY2hhbmdlcyBhcnJheSBpbmRpY2VzIGluIHRoZSBsaXN0ZW5lciBhcnJheSBiZWhpbmQgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRvZmYoZXZlbnQsIGxpc3RlbmVyKSB7XG5cdFx0dGhpcy52YWxpZGF0ZUxpc3RlbmVyXyhsaXN0ZW5lcik7XG5cdFx0aWYgKCF0aGlzLmV2ZW50c18pIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdGNvbnN0IGV2ZW50cyA9IHRoaXMudG9FdmVudHNBcnJheV8oZXZlbnQpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmV2ZW50c19bZXZlbnRzW2ldXSA9IHRoaXMucmVtb3ZlTWF0Y2hpbmdMaXN0ZW5lck9ianNfKFxuXHRcdFx0XHR0b0FycmF5KHRoaXMuZXZlbnRzX1tldmVudHNbaV1dKSxcblx0XHRcdFx0bGlzdGVuZXJcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3RlbmVycyBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudHMuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cblx0ICovXG5cdG9uKCkge1xuXHRcdHJldHVybiB0aGlzLmFkZExpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGhhbmRsZXIgdGhhdCBnZXRzIHRyaWdnZXJlZCB3aGVuIGFuIGV2ZW50IGlzIGxpc3RlbmVkIHRvIG9uIHRoaXNcblx0ICogaW5zdGFuY2UuXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGhhbmRsZXJcblx0ICovXG5cdG9uTGlzdGVuZXIoaGFuZGxlcikge1xuXHRcdHRoaXMubGlzdGVuZXJIYW5kbGVyc18gPSB0aGlzLmFkZEhhbmRsZXJfKFxuXHRcdFx0dGhpcy5saXN0ZW5lckhhbmRsZXJzXyxcblx0XHRcdGhhbmRsZXJcblx0XHQpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIG9uZSB0aW1lIGxpc3RlbmVyIGZvciB0aGUgZXZlbnRzLiBUaGlzIGxpc3RlbmVyIGlzIGludm9rZWQgb25seSB0aGVcblx0ICogbmV4dCB0aW1lIGVhY2ggZXZlbnQgaXMgZmlyZWQsIGFmdGVyIHdoaWNoIGl0IGlzIHJlbW92ZWQuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cblx0ICovXG5cdG9uY2UoZXZlbnRzLCBsaXN0ZW5lcikge1xuXHRcdHJldHVybiB0aGlzLm1hbnkoZXZlbnRzLCAxLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBhbGwgbGlzdGVuZXJzLCBvciB0aG9zZSBvZiB0aGUgc3BlY2lmaWVkIGV2ZW50cy4gSXQncyBub3QgYSBnb29kXG5cdCAqIGlkZWEgdG8gcmVtb3ZlIGxpc3RlbmVycyB0aGF0IHdlcmUgYWRkZWQgZWxzZXdoZXJlIGluIHRoZSBjb2RlLFxuXHQgKiBlc3BlY2lhbGx5IHdoZW4gaXQncyBvbiBhbiBlbWl0dGVyIHRoYXQgeW91IGRpZG4ndCBjcmVhdGUuXG5cdCAqIEBwYXJhbSB7KEFycmF5fHN0cmluZyk9fSBldmVudFxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fSBSZXR1cm5zIGVtaXR0ZXIsIHNvIGNhbGxzIGNhbiBiZSBjaGFpbmVkLlxuXHQgKi9cblx0cmVtb3ZlQWxsTGlzdGVuZXJzKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuZXZlbnRzXykge1xuXHRcdFx0aWYgKGV2ZW50KSB7XG5cdFx0XHRcdGNvbnN0IGV2ZW50cyA9IHRoaXMudG9FdmVudHNBcnJheV8oZXZlbnQpO1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdHRoaXMuZXZlbnRzX1tldmVudHNbaV1dID0gbnVsbDtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBhbGwgbGlzdGVuZXIgb2JqZWN0cyBmcm9tIHRoZSBnaXZlbiBhcnJheSB0aGF0IG1hdGNoIHRoZSBnaXZlblxuXHQgKiBsaXN0ZW5lciBmdW5jdGlvbi5cblx0ICogQHBhcmFtIHtBcnJheS48T2JqZWN0Pn0gbGlzdGVuZXJPYmpzXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHtBcnJheS48T2JqZWN0PnxPYmplY3R9IFRoZSBuZXcgbGlzdGVuZXJzIGFycmF5IGZvciB0aGlzIGV2ZW50LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRyZW1vdmVNYXRjaGluZ0xpc3RlbmVyT2Jqc18obGlzdGVuZXJPYmpzLCBsaXN0ZW5lcikge1xuXHRcdGNvbnN0IGZpbmFsTGlzdGVuZXJzID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lck9ianMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICghdGhpcy5tYXRjaGVzTGlzdGVuZXJfKGxpc3RlbmVyT2Jqc1tpXSwgbGlzdGVuZXIpKSB7XG5cdFx0XHRcdGZpbmFsTGlzdGVuZXJzLnB1c2gobGlzdGVuZXJPYmpzW2ldKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZpbmFsTGlzdGVuZXJzLmxlbmd0aCA+IDAgPyBmaW5hbExpc3RlbmVycyA6IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50cy5cblx0ICogQ2F1dGlvbjogY2hhbmdlcyBhcnJheSBpbmRpY2VzIGluIHRoZSBsaXN0ZW5lciBhcnJheSBiZWhpbmQgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRzXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fSBSZXR1cm5zIGVtaXR0ZXIsIHNvIGNhbGxzIGNhbiBiZSBjaGFpbmVkLlxuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0cmV0dXJuIHRoaXMub2ZmLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxuXG5cdC8qKlxuXHQgKiBSdW5zIHRoZSBoYW5kbGVycyB3aGVuIGFuIGV2ZW50IGlzIGxpc3RlbmVkIHRvLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0cnVuTGlzdGVuZXJIYW5kbGVyc18oZXZlbnQpIHtcblx0XHRsZXQgaGFuZGxlcnMgPSB0aGlzLmxpc3RlbmVySGFuZGxlcnNfO1xuXHRcdGlmIChoYW5kbGVycykge1xuXHRcdFx0aGFuZGxlcnMgPSB0b0FycmF5KGhhbmRsZXJzKTtcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgaGFuZGxlcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aGFuZGxlcnNbaV0oZXZlbnQpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSdW5zIHRoZSBnaXZlbiBsaXN0ZW5lcnMuXG5cdCAqIEBwYXJhbSB7IUFycmF5fSBsaXN0ZW5lcnNcblx0ICogQHBhcmFtIHshQXJyYXl9IGFyZ3Ncblx0ICogQHBhcmFtIHtPYmplY3R9IGZhY2FkZVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRydW5MaXN0ZW5lcnNfKGxpc3RlbmVycywgYXJncywgZmFjYWRlKSB7XG5cdFx0aWYgKGZhY2FkZSkge1xuXHRcdFx0YXJncy5wdXNoKGZhY2FkZSk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZGVmYXVsdExpc3RlbmVycyA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpXS5mbiB8fCBsaXN0ZW5lcnNbaV07XG5cdFx0XHRpZiAobGlzdGVuZXJzW2ldLmRlZmF1bHQpIHtcblx0XHRcdFx0ZGVmYXVsdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoIWZhY2FkZSB8fCAhZmFjYWRlLnByZXZlbnRlZERlZmF1bHQpIHtcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgZGVmYXVsdExpc3RlbmVycy5sZW5ndGg7IGorKykge1xuXHRcdFx0XHRkZWZhdWx0TGlzdGVuZXJzW2pdLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBjb25maWd1cmF0aW9uIG9wdGlvbiB3aGljaCBkZXRlcm1pbmVzIGlmIGFuIGV2ZW50IGZhY2FkZSBzaG91bGRcblx0ICogYmUgc2VudCBhcyBhIHBhcmFtIG9mIGxpc3RlbmVycyB3aGVuIGVtaXR0aW5nIGV2ZW50cy4gSWYgc2V0IHRvIHRydWUsIHRoZVxuXHQgKiBmYWNhZGUgd2lsbCBiZSBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoZSBsaXN0ZW5lci5cblx0ICogQHBhcmFtIHtib29sZWFufSBzaG91bGRVc2VGYWNhZGVcblx0ICogQHJldHVybiB7IU9iamVjdH0gUmV0dXJucyBlbWl0dGVyLCBzbyBjYWxscyBjYW4gYmUgY2hhaW5lZC5cblx0ICovXG5cdHNldFNob3VsZFVzZUZhY2FkZShzaG91bGRVc2VGYWNhZGUpIHtcblx0XHR0aGlzLnNob3VsZFVzZUZhY2FkZV8gPSBzaG91bGRVc2VGYWNhZGU7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgdGhlIHBhcmFtZXRlciB0byBhbiBhcnJheSBpZiBvbmx5IG9uZSBldmVudCBpcyBnaXZlbi4gUmV1c2VzIHRoZVxuXHQgKiBzYW1lIGFycmF5IGVhY2ggdGltZSB0aGlzIGNvbnZlcnNpb24gaXMgZG9uZSwgdG8gYXZvaWQgdXNpbmcgbW9yZSBtZW1vcnlcblx0ICogdGhhbiBuZWNlc3NhcnkuXG5cdCAqIEBwYXJhbSAgeyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRzXG5cdCAqIEByZXR1cm4geyFBcnJheX1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0dG9FdmVudHNBcnJheV8oZXZlbnRzKSB7XG5cdFx0aWYgKGlzU3RyaW5nKGV2ZW50cykpIHtcblx0XHRcdHNpbmdsZUFycmF5X1swXSA9IGV2ZW50cztcblx0XHRcdGV2ZW50cyA9IHNpbmdsZUFycmF5Xztcblx0XHR9XG5cdFx0cmV0dXJuIGV2ZW50cztcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGxpc3RlbmVyIGlzIHZhbGlkLCB0aHJvd2luZyBhbiBleGNlcHRpb24gd2hlbiBpdCdzIG5vdC5cblx0ICogQHBhcmFtICB7Kn0gbGlzdGVuZXJcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0dmFsaWRhdGVMaXN0ZW5lcl8obGlzdGVuZXIpIHtcblx0XHRpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdMaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0byBhbiBhcnJheVxuICogQHBhcmFtIHtPYmplY3R9IHZhbFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIHRvQXJyYXkodmFsKSB7XG5cdHZhbCA9IHZhbCB8fCBbXTtcblx0cmV0dXJuIEFycmF5LmlzQXJyYXkodmFsKSA/IHZhbCA6IFt2YWxdO1xufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudEVtaXR0ZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50RW1pdHRlclByb3h5IHV0aWxpdHkuIEl0J3MgcmVzcG9uc2libGUgZm9yIGxpbmtpbmcgdHdvIEV2ZW50RW1pdHRlclxuICogaW5zdGFuY2VzIHRvZ2V0aGVyLCBlbWl0dGluZyBldmVudHMgZnJvbSB0aGUgZmlyc3QgZW1pdHRlciB0aHJvdWdoIHRoZVxuICogc2Vjb25kIG9uZS4gVGhhdCBtZWFucyB0aGF0IGxpc3RlbmluZyB0byBhIHN1cHBvcnRlZCBldmVudCBvbiB0aGUgdGFyZ2V0XG4gKiBlbWl0dGVyIHdpbGwgbWVhbiBsaXN0ZW5pbmcgdG8gaXQgb24gdGhlIG9yaWdpbiBlbWl0dGVyIGFzIHdlbGwuXG4gKiBAZXh0ZW5kcyB7RGlzcG9zYWJsZX1cbiAqL1xuY2xhc3MgRXZlbnRFbWl0dGVyUHJveHkgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIEBwYXJhbSB7RXZlbnRFbWl0dGVyfSBvcmlnaW5FbWl0dGVyIEV2ZW50cyBvcmlnaW5hdGVkIG9uIHRoaXMgZW1pdHRlclxuXHQgKiB3aWxsIGJlIGZpcmVkIGZvciB0aGUgdGFyZ2V0IGVtaXR0ZXIncyBsaXN0ZW5lcnMgYXMgd2VsbC5cblx0ICogQHBhcmFtIHtFdmVudEVtaXR0ZXJ9IHRhcmdldEVtaXR0ZXIgRXZlbnQgbGlzdGVuZXJzIGF0dGFjaGVkIHRvIHRoaXMgZW1pdHRlclxuXHQgKiB3aWxsIGFsc28gYmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGV2ZW50IGlzIGZpcmVkIGJ5IHRoZSBvcmlnaW4gZW1pdHRlci5cblx0ICogQHBhcmFtIHtPYmplY3R9IGJsYWNrbGlzdCBPcHRpb25hbCBibGFja2xpc3Qgb2YgZXZlbnRzIHRoYXQgc2hvdWxkIG5vdCBiZVxuXHQgKiBwcm94aWVkLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gd2hpdGVsaXN0XG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihvcmlnaW5FbWl0dGVyLCB0YXJnZXRFbWl0dGVyLCBibGFja2xpc3QsIHdoaXRlbGlzdCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBNYXAgb2YgZXZlbnRzIHRoYXQgc2hvdWxkIG5vdCBiZSBwcm94aWVkLlxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYmxhY2tsaXN0XyA9IGJsYWNrbGlzdDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBvcmlnaW4gZW1pdHRlci4gVGhpcyBlbWl0dGVyJ3MgZXZlbnRzIHdpbGwgYmUgcHJveGllZCB0aHJvdWdoIHRoZVxuXHRcdCAqIHRhcmdldCBlbWl0dGVyLlxuXHRcdCAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMub3JpZ2luRW1pdHRlcl8gPSBvcmlnaW5FbWl0dGVyO1xuXG5cdFx0LyoqXG5cdFx0ICogQSBsaXN0IG9mIGV2ZW50cyB0aGF0IGFyZSBwZW5kaW5nIHRvIGJlIGxpc3RlbmVkIGJ5IGFuIGFjdHVhbCBvcmlnaW5cblx0XHQgKiBlbWl0dGVyLiBFdmVudHMgYXJlIHN0b3JlZCBoZXJlIHdoZW4gdGhlIG9yaWdpbiBkb2Vzbid0IGV4aXN0LCBzbyB0aGV5XG5cdFx0ICogY2FuIGJlIHNldCBvbiBhIG5ldyBvcmlnaW4gd2hlbiBvbmUgaXMgc2V0LlxuXHRcdCAqIEB0eXBlIHtBcnJheX1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5wZW5kaW5nRXZlbnRzXyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBhIG1hcCBvZiBldmVudHMgZnJvbSB0aGUgb3JpZ2luIGVtaXR0ZXIgdGhhdCBhcmUgYWxyZWFkeSBiZWluZyBwcm94aWVkLlxuXHRcdCAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAhRXZlbnRIYW5kbGU+fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSB0YXJnZXQgZW1pdHRlci4gVGhpcyBlbWl0dGVyIHdpbGwgZW1pdCBhbGwgZXZlbnRzIHRoYXQgY29tZSBmcm9tXG5cdFx0ICogdGhlIG9yaWdpbiBlbWl0dGVyLlxuXHRcdCAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMudGFyZ2V0RW1pdHRlcl8gPSB0YXJnZXRFbWl0dGVyO1xuXG5cdFx0LyoqXG5cdFx0ICogTWFwIG9mIGV2ZW50cyB0aGF0IHNob3VsZCBiZSBwcm94aWVkLiBJZiB3aGl0ZWxpc3QgaXMgc2V0IGJsYWNrbGlzdCBpcyBpZ25vcmVkLlxuXHRcdCAqIEB0eXBlIHtPYmplY3R9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMud2hpdGVsaXN0XyA9IHdoaXRlbGlzdDtcblxuXHRcdHRoaXMuc3RhcnRQcm94eV8oKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIHRoZSBnaXZlbiBsaXN0ZW5lciBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBUaGUgbGlzdGVuZWQgZXZlbnQncyBoYW5kbGUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGFkZExpc3RlbmVyXyhldmVudCwgbGlzdGVuZXIpIHtcblx0XHRyZXR1cm4gdGhpcy5vcmlnaW5FbWl0dGVyXy5vbihldmVudCwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5yZW1vdmVMaXN0ZW5lcnNfKCk7XG5cdFx0dGhpcy5wcm94aWVkRXZlbnRzXyA9IG51bGw7XG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG51bGw7XG5cdFx0dGhpcy50YXJnZXRFbWl0dGVyXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogRW1pdHMgdGhlIHNwZWNpZmllZCBldmVudCB0eXBlIG9uIHRoZSB0YXJnZXQgZW1pdHRlci5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0ZW1pdE9uVGFyZ2V0XyguLi5hcmdzKSB7XG5cdFx0dGhpcy50YXJnZXRFbWl0dGVyXy5lbWl0KC4uLmFyZ3MpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFByb3hpZXMgdGhlIGdpdmVuIGV2ZW50IGZyb20gdGhlIG9yaWdpbiB0byB0aGUgdGFyZ2V0IGVtaXR0ZXIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKi9cblx0cHJveHlFdmVudChldmVudCkge1xuXHRcdGlmICh0aGlzLnNob3VsZFByb3h5RXZlbnRfKGV2ZW50KSkge1xuXHRcdFx0dGhpcy50cnlUb0FkZExpc3RlbmVyXyhldmVudCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIHByb3h5IGxpc3RlbmVyIGZvciBhbGwgZXZlbnRzLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcnNfKCkge1xuXHRcdGlmICh0aGlzLnByb3hpZWRFdmVudHNfKSB7XG5cdFx0XHRjb25zdCBldmVudHMgPSBPYmplY3Qua2V5cyh0aGlzLnByb3hpZWRFdmVudHNfKTtcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdHRoaXMucHJveGllZEV2ZW50c19bZXZlbnRzW2ldXS5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5wcm94aWVkRXZlbnRzXyA9IG51bGw7XG5cdFx0fVxuXHRcdHRoaXMucGVuZGluZ0V2ZW50c18gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoYW5nZXMgdGhlIG9yaWdpbiBlbWl0dGVyLiBUaGlzIGF1dG9tYXRpY2FsbHkgZGV0YWNoZXMgYW55IGV2ZW50cyB0aGF0XG5cdCAqIHdlcmUgYWxyZWFkeSBiZWluZyBwcm94aWVkIGZyb20gdGhlIHByZXZpb3VzIGVtaXR0ZXIsIGFuZCBzdGFydHMgcHJveHlpbmdcblx0ICogdGhlbSBvbiB0aGUgbmV3IGVtaXR0ZXIgaW5zdGVhZC5cblx0ICogQHBhcmFtIHshRXZlbnRFbWl0dGVyfSBvcmlnaW5FbWl0dGVyXG5cdCAqL1xuXHRzZXRPcmlnaW5FbWl0dGVyKG9yaWdpbkVtaXR0ZXIpIHtcblx0XHRjb25zdCBldmVudHMgPVxuXHRcdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyAmJiB0aGlzLnByb3hpZWRFdmVudHNfXG5cdFx0XHRcdD8gT2JqZWN0LmtleXModGhpcy5wcm94aWVkRXZlbnRzXylcblx0XHRcdFx0OiB0aGlzLnBlbmRpbmdFdmVudHNfO1xuXHRcdHRoaXMub3JpZ2luRW1pdHRlcl8gPSBvcmlnaW5FbWl0dGVyO1xuXHRcdGlmIChldmVudHMpIHtcblx0XHRcdHRoaXMucmVtb3ZlTGlzdGVuZXJzXygpO1xuXHRcdFx0ZXZlbnRzLmZvckVhY2goZXZlbnQgPT4gdGhpcy5wcm94eUV2ZW50KGV2ZW50KSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXZlbnQgc2hvdWxkIGJlIHByb3hpZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzaG91bGRQcm94eUV2ZW50XyhldmVudCkge1xuXHRcdGlmICh0aGlzLndoaXRlbGlzdF8gJiYgIXRoaXMud2hpdGVsaXN0X1tldmVudF0pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuYmxhY2tsaXN0XyAmJiB0aGlzLmJsYWNrbGlzdF9bZXZlbnRdKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdHJldHVybiAhdGhpcy5wcm94aWVkRXZlbnRzXyB8fCAhdGhpcy5wcm94aWVkRXZlbnRzX1tldmVudF07XG5cdH1cblxuXHQvKipcblx0ICogU3RhcnRzIHByb3h5aW5nIGFsbCBldmVudHMgZnJvbSB0aGUgb3JpZ2luIHRvIHRoZSB0YXJnZXQgZW1pdHRlci5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0c3RhcnRQcm94eV8oKSB7XG5cdFx0dGhpcy50YXJnZXRFbWl0dGVyXy5vbkxpc3RlbmVyKHRoaXMucHJveHlFdmVudC5iaW5kKHRoaXMpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIG9yaWdpbiBlbWl0dGVyLCBpZiBpdCBleGlzdHMuIE90aGVyd2lzZSwgc3RvcmVzXG5cdCAqIHRoZSBwZW5kaW5nIGxpc3RlbmVyIHNvIGl0IGNhbiBiZSB1c2VkIG9uIGEgZnV0dXJlIG9yaWdpbiBlbWl0dGVyLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0dHJ5VG9BZGRMaXN0ZW5lcl8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy5vcmlnaW5FbWl0dGVyXykge1xuXHRcdFx0dGhpcy5wcm94aWVkRXZlbnRzXyA9IHRoaXMucHJveGllZEV2ZW50c18gfHwge307XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfW2V2ZW50XSA9IHRoaXMuYWRkTGlzdGVuZXJfKFxuXHRcdFx0XHRldmVudCxcblx0XHRcdFx0dGhpcy5lbWl0T25UYXJnZXRfLmJpbmQodGhpcywgZXZlbnQpXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnBlbmRpbmdFdmVudHNfID0gdGhpcy5wZW5kaW5nRXZlbnRzXyB8fCBbXTtcblx0XHRcdHRoaXMucGVuZGluZ0V2ZW50c18ucHVzaChldmVudCk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50RW1pdHRlclByb3h5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge0Rpc3Bvc2FibGV9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBFdmVudEhhbmRsZXIgdXRpbGl0eS4gSXQncyB1c2VmdWwgZm9yIGVhc2lseSByZW1vdmluZyBhIGdyb3VwIG9mXG4gKiBsaXN0ZW5lcnMgZnJvbSBkaWZmZXJlbnQgRXZlbnRFbWl0dGVyIGluc3RhbmNlcy5cbiAqIEBleHRlbmRzIHtEaXNwb3NhYmxlfVxuICovXG5jbGFzcyBFdmVudEhhbmRsZXIgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIEV2ZW50SGFuZGxlciBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEFuIGFycmF5IHRoYXQgaG9sZHMgdGhlIGFkZGVkIGV2ZW50IGhhbmRsZXMsIHNvIHRoZSBsaXN0ZW5lcnMgY2FuIGJlXG5cdFx0ICogcmVtb3ZlZCBsYXRlci5cblx0XHQgKiBAdHlwZSB7QXJyYXkuPEV2ZW50SGFuZGxlPn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudEhhbmRsZXNfID0gW107XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBldmVudCBoYW5kbGVzIHRvIGJlIHJlbW92ZWQgbGF0ZXIgdGhyb3VnaCB0aGUgYHJlbW92ZUFsbExpc3RlbmVyc2Bcblx0ICogbWV0aG9kLlxuXHQgKiBAcGFyYW0gey4uLighRXZlbnRIYW5kbGUpfSB2YXJfYXJnc1xuXHQgKi9cblx0YWRkKC4uLmFyZ3MpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5ldmVudEhhbmRsZXNfLnB1c2goYXJnc1tpXSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5ldmVudEhhbmRsZXNfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgdGhhdCBoYXZlIGJlZW4gYWRkZWQgdGhyb3VnaCB0aGUgYGFkZGAgbWV0aG9kLlxuXHQgKi9cblx0cmVtb3ZlQWxsTGlzdGVuZXJzKCkge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ldmVudEhhbmRsZXNfLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmV2ZW50SGFuZGxlc19baV0ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR9XG5cblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBbXTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudEhhbmRsZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXJyYXksIGlzU3RyaW5nfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgZG9tRGF0YSBmcm9tICcuL2RvbURhdGEnO1xuaW1wb3J0IHtFdmVudEhhbmRsZX0gZnJvbSAnbWV0YWwtZXZlbnRzJztcblxuLyoqXG4gKiBUaGlzIGlzIGEgc3BlY2lhbCBFdmVudEhhbmRsZSwgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgZG9tIGRlbGVnYXRlZCBldmVudHNcbiAqIChvbmx5IHRoZSBvbmVzIHRoYXQgcmVjZWl2ZSBhIHRhcmdldCBlbGVtZW50LCBub3QgYSBzZWxlY3RvciBzdHJpbmcpLlxuICogQGV4dGVuZHMge0V2ZW50SGFuZGxlfVxuICovXG5jbGFzcyBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZSBleHRlbmRzIEV2ZW50SGFuZGxlIHtcblx0LyoqXG5cdCAqIFRoZSBjb25zdHJ1Y3RvciBmb3IgYERvbURlbGVnYXRlZEV2ZW50SGFuZGxlYC5cblx0ICogQHBhcmFtIHshRXZlbnR9IGVtaXR0ZXIgRWxlbWVudCB0aGUgZXZlbnQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdGhhdCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0ICogQHBhcmFtIHtzdHJpbmc9fSBzZWxlY3RvciBBbiBvcHRpb25hbCBzZWxlY3RvciB1c2VkIHdoZW4gZGVsZWdhdGluZ1xuXHQgKiAgICAgdGhlIGV2ZW50LlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lciwgc2VsZWN0b3IpIHtcblx0XHRzdXBlcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIpO1xuXHRcdHRoaXMuc2VsZWN0b3JfID0gc2VsZWN0b3I7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdHJlbW92ZUxpc3RlbmVyKCkge1xuXHRcdGNvbnN0IGRlbGVnYXRpbmcgPSBkb21EYXRhLmdldCh0aGlzLmVtaXR0ZXJfLCAnZGVsZWdhdGluZycsIHt9KTtcblx0XHRjb25zdCBsaXN0ZW5lcnMgPSBkb21EYXRhLmdldCh0aGlzLmVtaXR0ZXJfLCAnbGlzdGVuZXJzJywge30pO1xuXHRcdGNvbnN0IHNlbGVjdG9yID0gdGhpcy5zZWxlY3Rvcl87XG5cdFx0Y29uc3QgYXJyID0gaXNTdHJpbmcoc2VsZWN0b3IpXG5cdFx0XHQ/IGRlbGVnYXRpbmdbdGhpcy5ldmVudF9dLnNlbGVjdG9yc1xuXHRcdFx0OiBsaXN0ZW5lcnM7XG5cdFx0Y29uc3Qga2V5ID0gaXNTdHJpbmcoc2VsZWN0b3IpID8gc2VsZWN0b3IgOiB0aGlzLmV2ZW50XztcblxuXHRcdGFycmF5LnJlbW92ZShhcnJba2V5XSB8fCBbXSwgdGhpcy5saXN0ZW5lcl8pO1xuXHRcdGlmIChhcnJba2V5XSAmJiBhcnJba2V5XS5sZW5ndGggPT09IDApIHtcblx0XHRcdGRlbGV0ZSBhcnJba2V5XTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RXZlbnRIYW5kbGV9IGZyb20gJ21ldGFsLWV2ZW50cyc7XG5cbi8qKlxuICogVGhpcyBpcyBhIHNwZWNpYWwgRXZlbnRIYW5kbGUsIHRoYXQgaXMgcmVzcG9uc2libGUgZm9yIGRvbSBldmVudHMsIGluc3RlYWRcbiAqIG9mIEV2ZW50RW1pdHRlciBldmVudHMuXG4gKiBAZXh0ZW5kcyB7RXZlbnRIYW5kbGV9XG4gKi9cbmNsYXNzIERvbUV2ZW50SGFuZGxlIGV4dGVuZHMgRXZlbnRIYW5kbGUge1xuXHQvKipcblx0ICogVGhlIGNvbnN0cnVjdG9yIGZvciBgRG9tRXZlbnRIYW5kbGVgLlxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IGVtaXR0ZXIgRW1pdHRlciB0aGUgZXZlbnQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdGhhdCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0ICogQHBhcmFtIHtib29sZWFufSBjYXB0dXJlIEZsYWcgaW5kaWNhdGluZyBpZiBsaXN0ZW5lciBzaG91bGQgYmUgdHJpZ2dlcmVkXG5cdCAqICAgZHVyaW5nIGNhcHR1cmUgcGhhc2UsIGluc3RlYWQgb2YgZHVyaW5nIHRoZSBidWJibGluZyBwaGFzZS4gRGVmYXVsdHMgdG8gZmFsc2UuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoZW1pdHRlciwgZXZlbnQsIGxpc3RlbmVyLCBjYXB0dXJlKSB7XG5cdFx0c3VwZXIoZW1pdHRlciwgZXZlbnQsIGxpc3RlbmVyKTtcblx0XHR0aGlzLmNhcHR1cmVfID0gY2FwdHVyZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0dGhpcy5lbWl0dGVyXy5yZW1vdmVFdmVudExpc3RlbmVyKFxuXHRcdFx0dGhpcy5ldmVudF8sXG5cdFx0XHR0aGlzLmxpc3RlbmVyXyxcblx0XHRcdHRoaXMuY2FwdHVyZV9cblx0XHQpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERvbUV2ZW50SGFuZGxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge1xuXHRpc0RlZixcblx0aXNEZWZBbmROb3ROdWxsLFxuXHRpc0RvY3VtZW50LFxuXHRpc0RvY3VtZW50RnJhZ21lbnQsXG5cdGlzRWxlbWVudCxcblx0aXNPYmplY3QsXG5cdGlzU3RyaW5nLFxuXHRvYmplY3QsXG59IGZyb20gJ21ldGFsJztcbmltcG9ydCBkb21EYXRhIGZyb20gJy4vZG9tRGF0YSc7XG5pbXBvcnQgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGUgZnJvbSAnLi9Eb21EZWxlZ2F0ZWRFdmVudEhhbmRsZSc7XG5pbXBvcnQgRG9tRXZlbnRIYW5kbGUgZnJvbSAnLi9Eb21FdmVudEhhbmRsZSc7XG5cbmNvbnN0IGVsZW1lbnRzQnlUYWdfID0ge307XG5jb25zdCBzdXBwb3J0Q2FjaGVfID0ge307XG5leHBvcnQgY29uc3QgY3VzdG9tRXZlbnRzID0ge307XG5cbmNvbnN0IExBU1RfQ09OVEFJTkVSID0gJ19fbWV0YWxfbGFzdF9jb250YWluZXJfXyc7XG5jb25zdCBVU0VfQ0FQVFVSRSA9IHtcblx0Ymx1cjogdHJ1ZSxcblx0ZXJyb3I6IHRydWUsXG5cdGZvY3VzOiB0cnVlLFxuXHRpbnZhbGlkOiB0cnVlLFxuXHRsb2FkOiB0cnVlLFxuXHRzY3JvbGw6IHRydWUsXG59O1xuXG4vKipcbiAqIEFkZHMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyB0byBhbiBlbGVtZW50LlxuICogQHBhcmFtIHshRWxlbWVudHwhTm9kZWxpc3R9IGVsZW1lbnRzIFRoZSBlbGVtZW50IG9yIGVsZW1lbnRzIHRvIGFkZCBDU1MgY2xhc3NlcyB0by5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc2VzIENTUyBjbGFzc2VzIHRvIGFkZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZENsYXNzZXMoZWxlbWVudHMsIGNsYXNzZXMpIHtcblx0aWYgKCFpc09iamVjdChlbGVtZW50cykgfHwgIWlzU3RyaW5nKGNsYXNzZXMpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcblx0XHRlbGVtZW50cyA9IFtlbGVtZW50c107XG5cdH1cblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKCdjbGFzc0xpc3QnIGluIGVsZW1lbnRzW2ldKSB7XG5cdFx0XHRhZGRDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudHNbaV0sIGNsYXNzZXMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhZGRDbGFzc2VzV2l0aG91dE5hdGl2ZV8oZWxlbWVudHNbaV0sIGNsYXNzZXMpO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIEFkZHMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyB0byBhbiBlbGVtZW50IHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gYWRkIENTUyBjbGFzc2VzIHRvLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gYWRkLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYWRkQ2xhc3Nlc1dpdGhOYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0Y2xhc3Nlcy5zcGxpdCgnICcpLmZvckVhY2goZnVuY3Rpb24oY2xhc3NOYW1lKSB7XG5cdFx0aWYgKGNsYXNzTmFtZSkge1xuXHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSk7XG5cdFx0fVxuXHR9KTtcbn1cblxuLyoqXG4gKiBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBFbGVtZW50LmNsYXNzTGlzdC5hZGQgZnVuY3Rpb24sIHRoaXMgbWV0aG9kXG4gKiBhZGRzIHRoZSByZXF1ZXN0ZWQgQ1NTIGNsYXNzZXMgdG8gYW4gZWxlbWVudCB3aXRob3V0IHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gYWRkIENTUyBjbGFzc2VzIHRvLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gYWRkLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYWRkQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0Y29uc3QgZWxlbWVudENsYXNzTmFtZSA9IGAgJHtlbGVtZW50LmNsYXNzTmFtZX0gYDtcblx0bGV0IGNsYXNzZXNUb0FwcGVuZCA9ICcnO1xuXG5cdGNsYXNzZXMgPSBjbGFzc2VzLnNwbGl0KCcgJyk7XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjbGFzc2VzLmxlbmd0aDsgaSsrKSB7XG5cdFx0Y29uc3QgY2xhc3NOYW1lID0gY2xhc3Nlc1tpXTtcblxuXHRcdGlmIChlbGVtZW50Q2xhc3NOYW1lLmluZGV4T2YoYCAke2NsYXNzTmFtZX0gYCkgPT09IC0xKSB7XG5cdFx0XHRjbGFzc2VzVG9BcHBlbmQgKz0gYCAke2NsYXNzTmFtZX1gO1xuXHRcdH1cblx0fVxuXG5cdGlmIChjbGFzc2VzVG9BcHBlbmQpIHtcblx0XHRlbGVtZW50LmNsYXNzTmFtZSA9IGVsZW1lbnQuY2xhc3NOYW1lICsgY2xhc3Nlc1RvQXBwZW5kO1xuXHR9XG59XG5cbi8qKlxuICogQWRkcyBhbiBldmVudCBsaXN0ZW5lciB0byB0aGUgZ2l2ZW4gZWxlbWVudCwgdG8gYmUgdHJpZ2dlcmVkIHZpYSBkZWxlZ2F0ZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGxpc3RlbmVyXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRFbGVtZW50TGlzdGVuZXJfKGVsZW1lbnQsIGV2ZW50TmFtZSwgbGlzdGVuZXIpIHtcblx0YWRkVG9BcnJfKGRvbURhdGEuZ2V0KGVsZW1lbnQsICdsaXN0ZW5lcnMnLCB7fSksIGV2ZW50TmFtZSwgbGlzdGVuZXIpO1xufVxuXG4vKipcbiAqIEFkZHMgYW4gZXZlbnQgbGlzdGVuZXIgdG8gdGhlIGdpdmVuIGVsZW1lbnQsIHRvIGJlIHRyaWdnZXJlZCB2aWEgZGVsZWdhdGVcbiAqIHNlbGVjdG9ycy5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBzZWxlY3RvclxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gbGlzdGVuZXJcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGFkZFNlbGVjdG9yTGlzdGVuZXJfKGVsZW1lbnQsIGV2ZW50TmFtZSwgc2VsZWN0b3IsIGxpc3RlbmVyKSB7XG5cdGNvbnN0IGRlbGVnYXRpbmdEYXRhID0gZG9tRGF0YS5nZXQoZWxlbWVudCwgJ2RlbGVnYXRpbmcnLCB7fSk7XG5cdGFkZFRvQXJyXyhkZWxlZ2F0aW5nRGF0YVtldmVudE5hbWVdLnNlbGVjdG9ycywgc2VsZWN0b3IsIGxpc3RlbmVyKTtcbn1cblxuLyoqXG4gKiBBZGRzIGEgdmFsdWUgdG8gYW4gYXJyYXkgaW5zaWRlIGFuIG9iamVjdCwgY3JlYXRpbmcgaXQgZmlyc3QgaWYgaXQgZG9lc24ndFxuICogeWV0IGV4aXN0LlxuICogQHBhcmFtIHshQXJyYXl9IGFyclxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYWRkVG9BcnJfKGFyciwga2V5LCB2YWx1ZSkge1xuXHRpZiAoIWFycltrZXldKSB7XG5cdFx0YXJyW2tleV0gPSBbXTtcblx0fVxuXHRhcnJba2V5XS5wdXNoKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBBdHRhY2hlcyBhIGRlbGVnYXRlIGxpc3RlbmVyLCB1bmxlc3MgdGhlcmUncyBhbHJlYWR5IG9uZSBhdHRhY2hlZC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGF0dGFjaERlbGVnYXRlRXZlbnRfKGVsZW1lbnQsIGV2ZW50TmFtZSkge1xuXHRsZXQgZGVsZWdhdGluZ0RhdGEgPSBkb21EYXRhLmdldChlbGVtZW50LCAnZGVsZWdhdGluZycsIHt9KTtcblx0aWYgKCFkZWxlZ2F0aW5nRGF0YVtldmVudE5hbWVdKSB7XG5cdFx0ZGVsZWdhdGluZ0RhdGFbZXZlbnROYW1lXSA9IHtcblx0XHRcdGhhbmRsZTogb24oXG5cdFx0XHRcdGVsZW1lbnQsXG5cdFx0XHRcdGV2ZW50TmFtZSxcblx0XHRcdFx0aGFuZGxlRGVsZWdhdGVFdmVudF8sXG5cdFx0XHRcdCEhVVNFX0NBUFRVUkVbZXZlbnROYW1lXVxuXHRcdFx0KSxcblx0XHRcdHNlbGVjdG9yczoge30sXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIElFMTEgZG9lc24ndCBzdXBwb3J0IEVsZW1lbnQuY2xvc2VzdCBmdW5jdGlvbiwgdGhpcyBtZXRob2RcbiAqIGdldHMgdGhlIGNsb3Nlc3QgZWxlbWVudCB1cCB0aGUgdHJlZSBmcm9tIHRoZSBnaXZlbiBlbGVtZW50IChpbmNsdWRpbmdcbiAqIGl0c2VsZikgdGhhdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgc2VsZWN0b3IsIG9yIG51bGwgaWYgbm9uZSBtYXRjaC5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xvc2VzdChlbGVtZW50LCBzZWxlY3Rvcikge1xuXHR3aGlsZSAoZWxlbWVudCAmJiAhbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpKSB7XG5cdFx0ZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcblx0fVxuXHRyZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBFbGVtZW50LmNsYXNzTGlzdC5hZGQgZnVuY3Rpb24sIHRoaXMgbWV0aG9kXG4gKiBhcHBlbmRzIGEgY2hpbGQgbm9kZSB3aXRoIHRleHQgb3Igb3RoZXIgbm9kZXMgdG8gYSBwYXJlbnQgbm9kZS4gSWZcbiAqIGNoaWxkIGlzIGEgSFRNTCBzdHJpbmcgaXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBhIGRvY3VtZW50XG4gKiBmcmFnbWVudCBiZWZvcmUgYXBwZW5kaW5nIGl0IHRvIHRoZSBwYXJlbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBwYXJlbnQgVGhlIG5vZGUgdG8gYXBwZW5kIG5vZGVzIHRvLlxuICogQHBhcmFtIHshKEVsZW1lbnR8Tm9kZUxpc3R8c3RyaW5nKX0gY2hpbGQgVGhlIHRoaW5nIHRvIGFwcGVuZCB0byB0aGUgcGFyZW50LlxuICogQHJldHVybiB7IUVsZW1lbnR9IFRoZSBhcHBlbmRlZCBjaGlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGVuZChwYXJlbnQsIGNoaWxkKSB7XG5cdGlmIChpc1N0cmluZyhjaGlsZCkpIHtcblx0XHRjaGlsZCA9IGJ1aWxkRnJhZ21lbnQoY2hpbGQpO1xuXHR9XG5cdGlmIChpc05vZGVMaXN0TGlrZShjaGlsZCkpIHtcblx0XHRjb25zdCBjaGlsZEFyciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGNoaWxkKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkQXJyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRwYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGRBcnJbaV0pO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRwYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGQpO1xuXHR9XG5cdHJldHVybiBjaGlsZDtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZm9yIGNvbnZlcnRpbmcgYSBIVE1MIHN0cmluZyBpbnRvIGEgZG9jdW1lbnQgZnJhZ21lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaHRtbFN0cmluZyBUaGUgSFRNTCBzdHJpbmcgdG8gY29udmVydC5cbiAqIEByZXR1cm4geyFFbGVtZW50fSBUaGUgcmVzdWx0aW5nIGRvY3VtZW50IGZyYWdtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRGcmFnbWVudChodG1sU3RyaW5nKSB7XG5cdGNvbnN0IHRlbXBEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0dGVtcERpdi5pbm5lckhUTUwgPSBgPGJyPiR7aHRtbFN0cmluZ31gO1xuXHR0ZW1wRGl2LnJlbW92ZUNoaWxkKHRlbXBEaXYuZmlyc3RDaGlsZCk7XG5cblx0Y29uc3QgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG5cdHdoaWxlICh0ZW1wRGl2LmZpcnN0Q2hpbGQpIHtcblx0XHRmcmFnbWVudC5hcHBlbmRDaGlsZCh0ZW1wRGl2LmZpcnN0Q2hpbGQpO1xuXHR9XG5cdHJldHVybiBmcmFnbWVudDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGZpcnN0IGVsZW1lbnQgY29udGFpbnMgdGhlIHNlY29uZCBvbmUuXG4gKiBAZGVwcmVjYXRlZCBVc2UgZWxlbWVudDEuY29udGFpbnMoZWxlbWVudDIpIGRpcmVjdGx5IGluc3RlYWQgb2YgdGhpcyBtZXRob2RcbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQxXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50MlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zKGVsZW1lbnQxLCBlbGVtZW50Mikge1xuXHRpZiAoaXNEb2N1bWVudChlbGVtZW50MSkpIHtcblx0XHQvLyBkb2N1bWVudC5jb250YWlucyBpcyBub3QgZGVmaW5lZCBvbiBJRTksIHNvIGNhbGwgaXQgb24gZG9jdW1lbnRFbGVtZW50IGluc3RlYWQuXG5cdFx0cmV0dXJuIGVsZW1lbnQxLmRvY3VtZW50RWxlbWVudC5jb250YWlucyhlbGVtZW50Mik7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGVsZW1lbnQxLmNvbnRhaW5zKGVsZW1lbnQyKTtcblx0fVxufVxuXG4vKipcbiAqIExpc3RlbnMgdG8gdGhlIHNwZWNpZmllZCBldmVudCBvbiB0aGUgZ2l2ZW4gRE9NIGVsZW1lbnQsIGJ1dCBvbmx5IGNhbGxzIHRoZVxuICogZ2l2ZW4gY2FsbGJhY2sgbGlzdGVuZXIgd2hlbiBpdCdzIHRyaWdnZXJlZCBieSBlbGVtZW50cyB0aGF0IG1hdGNoIHRoZVxuICogZ2l2ZW4gc2VsZWN0b3Igb3IgdGFyZ2V0IGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBET00gZWxlbWVudCB0aGUgZXZlbnQgc2hvdWxkIGJlIGxpc3RlbmVkIG9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIHRvLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IHNlbGVjdG9yT3JUYXJnZXQgRWl0aGVyIGFuIGVsZW1lbnQgb3IgY3NzIHNlbGVjdG9yXG4gKiAgICAgdGhhdCBzaG91bGQgbWF0Y2ggdGhlIGV2ZW50IGZvciB0aGUgbGlzdGVuZXIgdG8gYmUgdHJpZ2dlcmVkLlxuICogQHBhcmFtIHshZnVuY3Rpb24oIU9iamVjdCl9IGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudFxuICogICAgIGlzIHRyaWdnZXJlZC4gSXQgd2lsbCByZWNlaXZlIHRoZSBub3JtYWxpemVkIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IGRlZmF1bHRMaXN0ZW5lciBPcHRpb25hbCBmbGFnIGluZGljYXRpbmcgaWYgdGhpcyBpcyBhIGRlZmF1bHRcbiAqICAgICBsaXN0ZW5lci4gVGhhdCBtZWFucyB0aGF0IGl0IHdvdWxkIG9ubHkgYmUgZXhlY3V0ZWQgYWZ0ZXIgYWxsIG5vblxuICogICAgIGRlZmF1bHQgbGlzdGVuZXJzLCBhbmQgb25seSBpZiB0aGUgZXZlbnQgaXNuJ3QgcHJldmVudGVkIHZpYVxuICogICAgIGBwcmV2ZW50RGVmYXVsdGAuXG4gKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxlZ2F0ZShcblx0ZWxlbWVudCxcblx0ZXZlbnROYW1lLFxuXHRzZWxlY3Rvck9yVGFyZ2V0LFxuXHRjYWxsYmFjayxcblx0ZGVmYXVsdExpc3RlbmVyXG4pIHtcblx0Y29uc3QgY3VzdG9tQ29uZmlnID0gY3VzdG9tRXZlbnRzW2V2ZW50TmFtZV07XG5cdGlmIChjdXN0b21Db25maWcgJiYgY3VzdG9tQ29uZmlnLmRlbGVnYXRlKSB7XG5cdFx0ZXZlbnROYW1lID0gY3VzdG9tQ29uZmlnLm9yaWdpbmFsRXZlbnQ7XG5cdFx0Y2FsbGJhY2sgPSBjdXN0b21Db25maWcuaGFuZGxlci5iaW5kKGN1c3RvbUNvbmZpZywgY2FsbGJhY2spO1xuXHR9XG5cblx0aWYgKGRlZmF1bHRMaXN0ZW5lcikge1xuXHRcdC8vIFdyYXAgY2FsbGJhY2sgc28gd2UgZG9uJ3Qgc2V0IHByb3BlcnR5IGRpcmVjdGx5IG9uIGl0LlxuXHRcdGNhbGxiYWNrID0gY2FsbGJhY2suYmluZCgpO1xuXHRcdGNhbGxiYWNrLmRlZmF1bHRMaXN0ZW5lcl8gPSB0cnVlO1xuXHR9XG5cblx0YXR0YWNoRGVsZWdhdGVFdmVudF8oZWxlbWVudCwgZXZlbnROYW1lKTtcblx0aWYgKGlzU3RyaW5nKHNlbGVjdG9yT3JUYXJnZXQpKSB7XG5cdFx0YWRkU2VsZWN0b3JMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3Rvck9yVGFyZ2V0LCBjYWxsYmFjayk7XG5cdH0gZWxzZSB7XG5cdFx0YWRkRWxlbWVudExpc3RlbmVyXyhzZWxlY3Rvck9yVGFyZ2V0LCBldmVudE5hbWUsIGNhbGxiYWNrKTtcblx0fVxuXG5cdHJldHVybiBuZXcgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGUoXG5cdFx0aXNTdHJpbmcoc2VsZWN0b3JPclRhcmdldCkgPyBlbGVtZW50IDogc2VsZWN0b3JPclRhcmdldCxcblx0XHRldmVudE5hbWUsXG5cdFx0Y2FsbGJhY2ssXG5cdFx0aXNTdHJpbmcoc2VsZWN0b3JPclRhcmdldCkgPyBzZWxlY3Rvck9yVGFyZ2V0IDogbnVsbFxuXHQpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIGlmIHRoZSBlbGVtZW50IGlzIGFibGUgdG8gdHJpZ2dlciB0aGUgQ2xpY2sgZXZlbnQsXG4gKiBzaW11bGF0aW5nIGJyb3dzZXJzIGJlaGF2aW91ciwgYXZvaWRpbmcgZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGNhbGxlZCBieSB0cmlnZ2VyRXZlbnQgbWV0aG9kLlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gYmUgY2hlY2tlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUuXG4gKiBAcGFyYW0ge09iamVjdD19IGV2ZW50T2JqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNBYmxlVG9JbnRlcmFjdFdpdGhfKG5vZGUsIGV2ZW50TmFtZSwgZXZlbnRPYmopIHtcblx0aWYgKGV2ZW50T2JqICYmIGV2ZW50TmFtZSA9PT0gJ2NsaWNrJyAmJiBldmVudE9iai5idXR0b24gPT09IDIpIHtcblx0XHQvLyBGaXJlZm94IHRyaWdnZXJzIFwiY2xpY2tcIiBldmVudHMgb24gdGhlIGRvY3VtZW50IGZvciByaWdodCBjbGlja3MuIFRoaXNcblx0XHQvLyBjYXVzZXMgb3VyIGRlbGVnYXRlIGxvZ2ljIHRvIHRyaWdnZXIgaXQgZm9yIHJlZ3VsYXIgZWxlbWVudHMgdG9vLCB3aGljaFxuXHRcdC8vIHNob3VsZG4ndCBoYXBwZW4uIElnbm9yaW5nIHRoZW0gaGVyZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRjb25zdCBtYXRjaGVzU2VsZWN0b3IgPSBbXG5cdFx0J0JVVFRPTicsXG5cdFx0J0lOUFVUJyxcblx0XHQnU0VMRUNUJyxcblx0XHQnVEVYVEFSRUEnLFxuXHRcdCdGSUVMRFNFVCcsXG5cdF07XG5cdGlmIChldmVudE5hbWUgPT09ICdjbGljaycgJiYgbWF0Y2hlc1NlbGVjdG9yLmluZGV4T2Yobm9kZS50YWdOYW1lKSA+IC0xKSB7XG5cdFx0cmV0dXJuICEobm9kZS5kaXNhYmxlZCB8fCBwYXJlbnQobm9kZSwgJ2ZpZWxkc2V0W2Rpc2FibGVkXScpKTtcblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIE5vZGVMaXN0IG9yIGxpa2Ugb25lLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgbGlrZSBhIE5vZGVMaXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb2RlTGlzdExpa2UodmFsKSB7XG5cdHJldHVybiAoXG5cdFx0aXNEZWZBbmROb3ROdWxsKHZhbCkgJiZcblx0XHR0eXBlb2YgdmFsLmxlbmd0aCA9PT0gJ251bWJlcicgJiZcblx0XHR0eXBlb2YgdmFsLml0ZW0gPT09ICdmdW5jdGlvbidcblx0KTtcbn1cblxuLyoqXG4gKiBJbnNlcnRzIG5vZGUgaW4gZG9jdW1lbnQgYXMgbGFzdCBlbGVtZW50LlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gcmVtb3ZlIGNoaWxkcmVuIGZyb20uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnRlckRvY3VtZW50KG5vZGUpIHtcblx0bm9kZSAmJiBhcHBlbmQoZG9jdW1lbnQuYm9keSwgbm9kZSk7XG59XG5cbi8qKlxuICogUmVtb3ZlcyBub2RlIGZyb20gZG9jdW1lbnQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgRWxlbWVudCB0byByZW1vdmUgY2hpbGRyZW4gZnJvbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4aXREb2N1bWVudChub2RlKSB7XG5cdGlmIChub2RlICYmIG5vZGUucGFyZW50Tm9kZSkge1xuXHRcdG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcblx0fVxufVxuXG4vKipcbiAqIFRoaXMgaXMgY2FsbGVkIHdoZW4gYW4gZXZlbnQgaXMgdHJpZ2dlcmVkIGJ5IGEgZGVsZWdhdGUgbGlzdGVuZXIuIEFsbFxuICogbWF0Y2hpbmcgbGlzdGVuZXJzIG9mIHRoaXMgZXZlbnQgdHlwZSBmcm9tIGB0YXJnZXRgIHRvIGBjdXJyZW50VGFyZ2V0YCB3aWxsXG4gKiBiZSB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHBheWxvYWQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGhhbmRsZURlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdG5vcm1hbGl6ZURlbGVnYXRlRXZlbnRfKGV2ZW50KTtcblx0bGV0IHJldCA9IHRydWU7XG5cdGNvbnN0IGNvbnRhaW5lciA9IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XG5cdGNvbnN0IGRlZkZucyA9IFtdO1xuXG5cdHJldCAmPSB0cmlnZ2VyRGVsZWdhdGVkTGlzdGVuZXJzXyhjb250YWluZXIsIGV2ZW50LCBkZWZGbnMpO1xuXHRyZXQgJj0gdHJpZ2dlckRlZmF1bHREZWxlZ2F0ZWRMaXN0ZW5lcnNfKGRlZkZucywgZXZlbnQpO1xuXG5cdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gbnVsbDtcblx0ZXZlbnRbTEFTVF9DT05UQUlORVJdID0gY29udGFpbmVyO1xuXHRyZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBoYXMgdGhlIHJlcXVlc3RlZCBjc3MgY2xhc3MuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lKSB7XG5cdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XG5cdFx0cmV0dXJuIGhhc0NsYXNzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3NOYW1lKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gaGFzQ2xhc3NXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc05hbWUpO1xuXHR9XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgcmVxdWVzdGVkIGNzcyBjbGFzcyB1c2luZyBjbGFzc0xpc3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gaGFzQ2xhc3NXaXRoTmF0aXZlXyhlbGVtZW50LCBjbGFzc05hbWUpIHtcblx0cmV0dXJuIChcblx0XHRjbGFzc05hbWUuaW5kZXhPZignICcpID09PSAtMSAmJiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpXG5cdCk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgcmVxdWVzdGVkIGNzcyBjbGFzcyB3aXRob3V0IHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBoYXNDbGFzc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuXHRyZXR1cm4gKFxuXHRcdGAgJHtlbGVtZW50LmNsYXNzTmFtZX0gYC5pbmRleE9mKGAgJHtjbGFzc05hbWV9IGApID49IDAgJiZcblx0XHRjbGFzc05hbWUuc3BsaXQoJyAnKS5sZW5ndGggPT09IDFcblx0KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgZW1wdHkgb3Igbm90LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkoZWxlbWVudCkge1xuXHRyZXR1cm4gZWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMDtcbn1cblxuLyoqXG4gKiBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBFbGVtZW50Lm1hdGNoZXMgZnVuY3Rpb24sIHRoaXMgbWV0aG9kXG4gKiBjaGVjayBpZiBhbiBlbGVtZW50IG1hdGNoZXMgYSBnaXZlbiBzZWxlY3Rvci5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0aWYgKCFlbGVtZW50IHx8IGVsZW1lbnQubm9kZVR5cGUgIT09IDEpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRjb25zdCBwID0gRWxlbWVudC5wcm90b3R5cGU7XG5cdGNvbnN0IG0gPVxuXHRcdHAubWF0Y2hlcyB8fFxuXHRcdHAud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0cC5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRwLm1zTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0cC5vTWF0Y2hlc1NlbGVjdG9yO1xuXHRpZiAobSkge1xuXHRcdHJldHVybiBtLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpO1xuXHR9XG5cblx0cmV0dXJuIG1hdGNoRmFsbGJhY2tfKGVsZW1lbnQsIHNlbGVjdG9yKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IG1hdGNoZXMgYSBnaXZlbiBzZWxlY3RvciwgdXNpbmcgYW4gaW50ZXJuYWwgaW1wbGVtZW50YXRpb25cbiAqIGluc3RlYWQgb2YgY2FsbGluZyBleGlzdGluZyBqYXZhc2NyaXB0IGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gbWF0Y2hGYWxsYmFja18oZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0Y29uc3QgcGFyZW50Tm9kZSA9IGVsZW1lbnQucGFyZW50Tm9kZTtcblxuXHRpZiAocGFyZW50Tm9kZSkge1xuXHRcdGNvbnN0IG5vZGVzID0gcGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyArK2kpIHtcblx0XHRcdGlmIChub2Rlc1tpXSA9PT0gZWxlbWVudCkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbmV4dCBzaWJsaW5nIG9mIHRoZSBnaXZlbiBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkXG4gKiBzZWxlY3Rvciwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHs/c3RyaW5nfSBzZWxlY3RvclxuICogQHJldHVybiB7RWxlbWVudHxudWxsfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbmV4dChlbGVtZW50LCBzZWxlY3Rvcikge1xuXHRkbyB7XG5cdFx0ZWxlbWVudCA9IGVsZW1lbnQubmV4dFNpYmxpbmc7XG5cdFx0aWYgKGVsZW1lbnQgJiYgbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpKSB7XG5cdFx0XHRyZXR1cm4gZWxlbWVudDtcblx0XHR9XG5cdH0gd2hpbGUgKGVsZW1lbnQpO1xuXHRyZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIHRoZSBldmVudCBwYXlsb2FkIGZvciBkZWxlZ2F0ZSBsaXN0ZW5lcnMuXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZURlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdGV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IHN0b3BQcm9wYWdhdGlvbl87XG5cdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9IHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbl87XG59XG5cbi8qKlxuICogTGlzdGVucyB0byB0aGUgc3BlY2lmaWVkIGV2ZW50IG9uIHRoZSBnaXZlbiBET00gZWxlbWVudC4gVGhpcyBmdW5jdGlvbiBub3JtYWxpemVzXG4gKiBET00gZXZlbnQgcGF5bG9hZHMgYW5kIGZ1bmN0aW9ucyBzbyB0aGV5J2xsIHdvcmsgdGhlIHNhbWUgd2F5IG9uIGFsbCBzdXBwb3J0ZWRcbiAqIGJyb3dzZXJzLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IGVsZW1lbnQgVGhlIERPTSBlbGVtZW50IHRvIGxpc3RlbiB0byB0aGUgZXZlbnQgb24sIG9yXG4gKiAgIGEgc2VsZWN0b3IgdGhhdCBzaG91bGQgYmUgZGVsZWdhdGVkIG9uIHRoZSBlbnRpcmUgZG9jdW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gdG8uXG4gKiBAcGFyYW0geyFmdW5jdGlvbighT2JqZWN0KX0gY2FsbGJhY2sgRnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzXG4gKiAgIHRyaWdnZXJlZC4gSXQgd2lsbCByZWNlaXZlIHRoZSBub3JtYWxpemVkIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2FwdHVyZSBGbGFnIGluZGljYXRpbmcgaWYgbGlzdGVuZXIgc2hvdWxkIGJlIHRyaWdnZXJlZFxuICogICBkdXJpbmcgY2FwdHVyZSBwaGFzZSwgaW5zdGVhZCBvZiBkdXJpbmcgdGhlIGJ1YmJsaW5nIHBoYXNlLiBEZWZhdWx0cyB0byBmYWxzZS5cbiAqIEByZXR1cm4geyFEb21FdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpIHtcblx0aWYgKGlzU3RyaW5nKGVsZW1lbnQpKSB7XG5cdFx0cmV0dXJuIGRlbGVnYXRlKGRvY3VtZW50LCBldmVudE5hbWUsIGVsZW1lbnQsIGNhbGxiYWNrKTtcblx0fVxuXHRjb25zdCBjdXN0b21Db25maWcgPSBjdXN0b21FdmVudHNbZXZlbnROYW1lXTtcblx0aWYgKGN1c3RvbUNvbmZpZyAmJiBjdXN0b21Db25maWcuZXZlbnQpIHtcblx0XHRldmVudE5hbWUgPSBjdXN0b21Db25maWcub3JpZ2luYWxFdmVudDtcblx0XHRjYWxsYmFjayA9IGN1c3RvbUNvbmZpZy5oYW5kbGVyLmJpbmQoY3VzdG9tQ29uZmlnLCBjYWxsYmFjayk7XG5cdH1cblx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xuXHRyZXR1cm4gbmV3IERvbUV2ZW50SGFuZGxlKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xufVxuXG4vKipcbiAqIElFMTEgZG9lc24ndCBzdXBwb3J0IG9uY2UgZXZlbnQgbGlzdGVuZXIgb3B0aW9uLCB0aGlzIG1ldGhvZFxuICogTGlzdGVucyB0byB0aGUgc3BlY2lmaWVkIGV2ZW50IG9uIHRoZSBnaXZlbiBET00gZWxlbWVudCBvbmNlLiBUaGlzXG4gKiBmdW5jdGlvbiBub3JtYWxpemVzIERPTSBldmVudCBwYXlsb2FkcyBhbmQgZnVuY3Rpb25zIHNvIHRoZXknbGwgd29yayB0aGVcbiAqIHNhbWUgd2F5IG9uIGFsbCBzdXBwb3J0ZWQgYnJvd3NlcnMuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBET00gZWxlbWVudCB0byBsaXN0ZW4gdG8gdGhlIGV2ZW50IG9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIHRvLlxuICogQHBhcmFtIHshZnVuY3Rpb24oIU9iamVjdCl9IGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudFxuICogICBpcyB0cmlnZ2VyZWQuIEl0IHdpbGwgcmVjZWl2ZSB0aGUgbm9ybWFsaXplZCBldmVudCBvYmplY3QuXG4gKiBAcmV0dXJuIHshRG9tRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmNlKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcblx0Y29uc3QgZG9tRXZlbnRIYW5kbGUgPSBvbihlbGVtZW50LCBldmVudE5hbWUsIGZ1bmN0aW9uKCkge1xuXHRcdGRvbUV2ZW50SGFuZGxlLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0cmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fSk7XG5cdHJldHVybiBkb21FdmVudEhhbmRsZTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBmaXJzdCBwYXJlbnQgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudCB0aGF0IG1hdGNoZXMgdGhlIHNwZWNpZmllZFxuICogc2VsZWN0b3IsIG9yIG51bGwgaWYgbm9uZSBtYXRjaC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzZWxlY3RvclxuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcmVudChlbGVtZW50LCBzZWxlY3Rvcikge1xuXHRyZXR1cm4gY2xvc2VzdChlbGVtZW50LnBhcmVudE5vZGUsIHNlbGVjdG9yKTtcbn1cblxuLyoqXG4gKiBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBFbGVtZW50LnByZXBlbmQgZnVuY3Rpb24sIHRoaXMgbWV0aG9kXG4gKiBpbnNlcnRzIGEgbm9kZSBiZWZvcmUgZmlyc3QgY2hpbGQgb2YgdGhlIHBhcmVudC4gSWYgY2hpbGQgaXMgYSBIVE1MIHN0cmluZ1xuICogaXQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gZG9jdW1lbnQgZnJhZ21lbnQgYmVmb3JlIHByZXBlbmRpbmcgaXQgdG8gdGhlIHBhcmVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IHBhcmVudCBUaGUgbm9kZSB0byBwcmVwZW5kIHRvLlxuICogQHBhcmFtIHshKEVsZW1lbnR8Tm9kZUxpc3R8c3RyaW5nKX0gY2hpbGQgVGhlIHRoaW5nIHRvIHByZXBlbmQgdG8gdGhlIHBhcmVudC5cbiAqIEByZXR1cm4geyFFbGVtZW50fSBUaGUgcHJlcGVuZGVkIGNoaWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlcGVuZChwYXJlbnQsIGNoaWxkKSB7XG5cdGlmIChpc1N0cmluZyhjaGlsZCkpIHtcblx0XHRjaGlsZCA9IGJ1aWxkRnJhZ21lbnQoY2hpbGQpO1xuXHR9XG5cblx0aWYgKCFpc05vZGVMaXN0TGlrZShjaGlsZCkgJiYgIWlzRGVmQW5kTm90TnVsbChwYXJlbnQuZmlyc3RDaGlsZCkpIHtcblx0XHRyZXR1cm4gYXBwZW5kKHBhcmVudCwgY2hpbGQpO1xuXHR9XG5cblx0aWYgKGlzTm9kZUxpc3RMaWtlKGNoaWxkKSkge1xuXHRcdGNvbnN0IGNoaWxkQXJyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoY2hpbGQpO1xuXHRcdGZvciAobGV0IGkgPSBjaGlsZEFyci5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXHRcdFx0cGFyZW50Lmluc2VydEJlZm9yZShjaGlsZEFycltpXSwgcGFyZW50LmZpcnN0Q2hpbGQpO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBwYXJlbnQuZmlyc3RDaGlsZCk7XG5cdH1cblxuXHRyZXR1cm4gY2hpbGQ7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgY3VzdG9tIGV2ZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgY3VzdG9tIGV2ZW50LlxuICogQHBhcmFtIHshT2JqZWN0fSBjdXN0b21Db25maWcgQW4gb2JqZWN0IHdpdGggaW5mb3JtYXRpb24gYWJvdXQgaG93IHRoZSBldmVudFxuICogICBzaG91bGQgYmUgaGFuZGxlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyQ3VzdG9tRXZlbnQoZXZlbnROYW1lLCBjdXN0b21Db25maWcpIHtcblx0Y3VzdG9tRXZlbnRzW2V2ZW50TmFtZV0gPSBjdXN0b21Db25maWc7XG59XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwgdGhlIGNoaWxkIG5vZGVzIG9uIGEgRE9NIG5vZGUuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgRWxlbWVudCB0byByZW1vdmUgY2hpbGRyZW4gZnJvbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUNoaWxkcmVuKG5vZGUpIHtcblx0bGV0IGNoaWxkO1xuXHR3aGlsZSAoKGNoaWxkID0gbm9kZS5maXJzdENoaWxkKSkge1xuXHRcdG5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuXHR9XG59XG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIGZyb20gYW4gZWxlbWVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR8IU5vZGVMaXN0fSBlbGVtZW50cyBUaGUgZWxlbWVudCBvciBlbGVtZW50cyB0byByZW1vdmUgQ1NTIGNsYXNzZXMgZnJvbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc2VzIENTUyBjbGFzc2VzIHRvIHJlbW92ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUNsYXNzZXMoZWxlbWVudHMsIGNsYXNzZXMpIHtcblx0aWYgKCFpc09iamVjdChlbGVtZW50cykgfHwgIWlzU3RyaW5nKGNsYXNzZXMpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcblx0XHRlbGVtZW50cyA9IFtlbGVtZW50c107XG5cdH1cblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKCdjbGFzc0xpc3QnIGluIGVsZW1lbnRzW2ldKSB7XG5cdFx0XHRyZW1vdmVDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudHNbaV0sIGNsYXNzZXMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZW1vdmVDbGFzc2VzV2l0aG91dE5hdGl2ZV8oZWxlbWVudHNbaV0sIGNsYXNzZXMpO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byByZW1vdmUgQ1NTIGNsYXNzZXMgZnJvbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc2VzIENTUyBjbGFzc2VzIHRvIHJlbW92ZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUNsYXNzZXNXaXRoTmF0aXZlXyhlbGVtZW50LCBjbGFzc2VzKSB7XG5cdGNsYXNzZXMuc3BsaXQoJyAnKS5mb3JFYWNoKGZ1bmN0aW9uKGNsYXNzTmFtZSkge1xuXHRcdGlmIChjbGFzc05hbWUpIHtcblx0XHRcdGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpO1xuXHRcdH1cblx0fSk7XG59XG5cbi8qKlxuICogSUUxMSBkb2Vzbid0IHN1cHBvcnQgRWxlbWVudC5jbGFzc0xpc3QsIHRoaXMgbWV0aG9kXG4gKiByZW1vdmVzIHRoZSByZXF1ZXN0ZWQgQ1NTIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50IHdpdGhvdXQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byByZW1vdmUgQ1NTIGNsYXNzZXMgZnJvbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc2VzIENTUyBjbGFzc2VzIHRvIHJlbW92ZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUNsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc2VzKSB7XG5cdGxldCBlbGVtZW50Q2xhc3NOYW1lID0gYCAke2VsZW1lbnQuY2xhc3NOYW1lfSBgO1xuXG5cdGNsYXNzZXMgPSBjbGFzc2VzLnNwbGl0KCcgJyk7XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjbGFzc2VzLmxlbmd0aDsgaSsrKSB7XG5cdFx0ZWxlbWVudENsYXNzTmFtZSA9IGVsZW1lbnRDbGFzc05hbWUucmVwbGFjZShgICR7Y2xhc3Nlc1tpXX0gYCwgJyAnKTtcblx0fVxuXG5cdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudENsYXNzTmFtZS50cmltKCk7XG59XG5cbi8qKlxuICogUmVwbGFjZXMgdGhlIGZpcnN0IGVsZW1lbnQgd2l0aCB0aGUgc2Vjb25kLlxuICogQGRlcHJlY2F0ZWQgVXNlIGVsZW1lbnQxLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGVsZW1lbnQyLCBlbGVtZW50MSlcbiAqIGRpcmVjdGx5IGluc3RlYWQgb2YgdGhpcyBtZXRob2RcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudDFcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudDJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2UoZWxlbWVudDEsIGVsZW1lbnQyKSB7XG5cdGlmIChlbGVtZW50MSAmJiBlbGVtZW50MiAmJiBlbGVtZW50MSAhPT0gZWxlbWVudDIgJiYgZWxlbWVudDEucGFyZW50Tm9kZSkge1xuXHRcdGVsZW1lbnQxLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGVsZW1lbnQyLCBlbGVtZW50MSk7XG5cdH1cbn1cblxuLyoqXG4gKiBUaGUgZnVuY3Rpb24gdGhhdCByZXBsYWNlcyBgc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uX2AgZm9yIGV2ZW50cy5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbl8oKSB7XG5cdGNvbnN0IGV2ZW50ID0gdGhpczsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRldmVudC5zdG9wcGVkID0gdHJ1ZTtcblx0ZXZlbnQuc3RvcHBlZEltbWVkaWF0ZSA9IHRydWU7XG5cdEV2ZW50LnByb3RvdHlwZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24uY2FsbChldmVudCk7XG59XG5cbi8qKlxuICogVGhlIGZ1bmN0aW9uIHRoYXQgcmVwbGFjZXMgYHN0b3BQcm9wYWdhdGlvbmAgZm9yIGV2ZW50cy5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHN0b3BQcm9wYWdhdGlvbl8oKSB7XG5cdGNvbnN0IGV2ZW50ID0gdGhpczsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRldmVudC5zdG9wcGVkID0gdHJ1ZTtcblx0RXZlbnQucHJvdG90eXBlLnN0b3BQcm9wYWdhdGlvbi5jYWxsKGV2ZW50KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGVsZW1lbnQgc3VwcG9ydHMgdGhlIGdpdmVuIGV2ZW50IHR5cGUuXG4gKiBAcGFyYW0geyFFbGVtZW50fHN0cmluZ30gZWxlbWVudCBUaGUgRE9NIGVsZW1lbnQgb3IgZWxlbWVudCB0YWcgbmFtZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGNoZWNrLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1cHBvcnRzRXZlbnQoZWxlbWVudCwgZXZlbnROYW1lKSB7XG5cdGlmIChjdXN0b21FdmVudHNbZXZlbnROYW1lXSkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0aWYgKGlzU3RyaW5nKGVsZW1lbnQpKSB7XG5cdFx0aWYgKCFlbGVtZW50c0J5VGFnX1tlbGVtZW50XSkge1xuXHRcdFx0ZWxlbWVudHNCeVRhZ19bZWxlbWVudF0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGVsZW1lbnQpO1xuXHRcdH1cblx0XHRlbGVtZW50ID0gZWxlbWVudHNCeVRhZ19bZWxlbWVudF07XG5cdH1cblxuXHRjb25zdCB0YWcgPSBlbGVtZW50LnRhZ05hbWU7XG5cdGlmICghc3VwcG9ydENhY2hlX1t0YWddIHx8ICFzdXBwb3J0Q2FjaGVfW3RhZ10uaGFzT3duUHJvcGVydHkoZXZlbnROYW1lKSkge1xuXHRcdHN1cHBvcnRDYWNoZV9bdGFnXSA9IHN1cHBvcnRDYWNoZV9bdGFnXSB8fCB7fTtcblx0XHRzdXBwb3J0Q2FjaGVfW3RhZ11bZXZlbnROYW1lXSA9ICdvbicgKyBldmVudE5hbWUgaW4gZWxlbWVudDtcblx0fVxuXHRyZXR1cm4gc3VwcG9ydENhY2hlX1t0YWddW2V2ZW50TmFtZV07XG59XG5cbi8qKlxuICogVGhpcyB0cmlnZ2VycyBhbGwgZGVmYXVsdCBtYXRjaGVkIGRlbGVnYXRlZCBsaXN0ZW5lcnMgb2YgYSBnaXZlbiBldmVudCB0eXBlLlxuICogQHBhcmFtIHshQXJyYXl9IGRlZkZucyBBcnJheSB0byBjb2xsZWN0IGRlZmF1bHQgbGlzdGVuZXJzIGluLCBpbnN0ZWFkXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlckRlZmF1bHREZWxlZ2F0ZWRMaXN0ZW5lcnNfKGRlZkZucywgZXZlbnQpIHtcblx0bGV0IHJldCA9IHRydWU7XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBkZWZGbnMubGVuZ3RoICYmICFldmVudC5kZWZhdWx0UHJldmVudGVkOyBpKyspIHtcblx0XHRldmVudC5kZWxlZ2F0ZVRhcmdldCA9IGRlZkZuc1tpXS5lbGVtZW50O1xuXHRcdHJldCAmPSBkZWZGbnNbaV0uZm4oZXZlbnQpO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBUaGlzIHRyaWdnZXJzIGFsbCBtYXRjaGVkIGRlbGVnYXRlZCBsaXN0ZW5lcnMgb2YgYSBnaXZlbiBldmVudCB0eXBlIHdoZW4gaXRzXG4gKiBkZWxlZ2F0ZWQgdGFyZ2V0IGlzIGFibGUgdG8gaW50ZXJhY3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBjb250YWluZXJcbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHBhcmFtIHshQXJyYXl9IGRlZmF1bHRGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogICAgIG9mIHJ1bm5pbmcgdGhlbS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlckRlbGVnYXRlZExpc3RlbmVyc18oY29udGFpbmVyLCBldmVudCwgZGVmYXVsdEZucykge1xuXHRsZXQgcmV0ID0gdHJ1ZTtcblx0bGV0IGN1cnJFbGVtZW50ID0gZXZlbnQudGFyZ2V0O1xuXHRjb25zdCBsaW1pdCA9IGNvbnRhaW5lci5wYXJlbnROb2RlO1xuXG5cdHdoaWxlIChjdXJyRWxlbWVudCAmJiBjdXJyRWxlbWVudCAhPT0gbGltaXQgJiYgIWV2ZW50LnN0b3BwZWQpIHtcblx0XHRpZiAoaXNBYmxlVG9JbnRlcmFjdFdpdGhfKGN1cnJFbGVtZW50LCBldmVudC50eXBlLCBldmVudCkpIHtcblx0XHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gY3VyckVsZW1lbnQ7XG5cdFx0XHRyZXQgJj0gdHJpZ2dlckVsZW1lbnRMaXN0ZW5lcnNfKGN1cnJFbGVtZW50LCBldmVudCwgZGVmYXVsdEZucyk7XG5cdFx0XHRyZXQgJj0gdHJpZ2dlclNlbGVjdG9yTGlzdGVuZXJzXyhcblx0XHRcdFx0Y29udGFpbmVyLFxuXHRcdFx0XHRjdXJyRWxlbWVudCxcblx0XHRcdFx0ZXZlbnQsXG5cdFx0XHRcdGRlZmF1bHRGbnNcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGN1cnJFbGVtZW50ID0gY3VyckVsZW1lbnQucGFyZW50Tm9kZTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIGFyZ3VtZW50IHRvIGEgRE9NIGVsZW1lbnQuIFN0cmluZ3MgYXJlIGFzc3VtZWQgdG9cbiAqIGJlIHNlbGVjdG9ycywgYW5kIHNvIGEgbWF0Y2hlZCBlbGVtZW50IHdpbGwgYmUgcmV0dXJuZWQuIElmIHRoZSBhcmdcbiAqIGlzIGFscmVhZHkgYSBET00gZWxlbWVudCBpdCB3aWxsIGJlIHRoZSByZXR1cm4gdmFsdWUuXG4gKiBAcGFyYW0ge3N0cmluZ3xFbGVtZW50fERvY3VtZW50fSBzZWxlY3Rvck9yRWxlbWVudFxuICogQHJldHVybiB7RWxlbWVudH0gVGhlIGNvbnZlcnRlZCBlbGVtZW50LCBvciBudWxsIGlmIG5vbmUgd2FzIGZvdW5kLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9FbGVtZW50KHNlbGVjdG9yT3JFbGVtZW50KSB7XG5cdGlmIChcblx0XHRpc0VsZW1lbnQoc2VsZWN0b3JPckVsZW1lbnQpIHx8XG5cdFx0aXNEb2N1bWVudChzZWxlY3Rvck9yRWxlbWVudCkgfHxcblx0XHRpc0RvY3VtZW50RnJhZ21lbnQoc2VsZWN0b3JPckVsZW1lbnQpXG5cdCkge1xuXHRcdHJldHVybiBzZWxlY3Rvck9yRWxlbWVudDtcblx0fSBlbHNlIGlmIChpc1N0cmluZyhzZWxlY3Rvck9yRWxlbWVudCkpIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvck9yRWxlbWVudCk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIG9yIHJlbW92ZXMgb25lIG9yIG1vcmUgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQuIElmIGFueSBvZiB0aGUgY2xhc3Nlc1xuICogaXMgcHJlc2VudCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQsIG9yIGFkZGVkIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgd2hpY2ggY2xhc3NlcyB3aWxsIGJlIHRvZ2dsZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBUaGUgY2xhc3NlcyB3aGljaCBoYXZlIHRvIGFkZGVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvZ2dsZUNsYXNzZXMoZWxlbWVudCwgY2xhc3Nlcykge1xuXHRpZiAoIWlzT2JqZWN0KGVsZW1lbnQpIHx8ICFpc1N0cmluZyhjbGFzc2VzKSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XG5cdFx0dG9nZ2xlQ2xhc3Nlc1dpdGhOYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpO1xuXHR9IGVsc2Uge1xuXHRcdHRvZ2dsZUNsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc2VzKTtcblx0fVxufVxuXG4vKipcbiAqIEFkZHMgb3IgcmVtb3ZlcyBvbmUgb3IgbW9yZSBjbGFzc2VzIGZyb20gYW4gZWxlbWVudCB1c2luZyBjbGFzc0xpc3QuXG4gKiBJZiBhbnkgb2YgdGhlIGNsYXNzZXMgaXMgcHJlc2VudCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQsXG4gKiBvciBhZGRlZCBvdGhlcndpc2UuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHdoaWNoIGNsYXNzZXMgd2lsbCBiZSB0b2dnbGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgVGhlIGNsYXNzZXMgd2hpY2ggaGF2ZSB0byBhZGRlZCBvciByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoY2xhc3NOYW1lKTtcblx0fSk7XG59XG5cbi8qKlxuICogSUUxMSBkb2Vzbid0IHN1cHBvcnQgRWxlbWVudC5jbGFzc0xpc3QsIHRoaXMgbWV0aG9kXG4gKiBhZGRzIG9yIHJlbW92ZXMgb25lIG9yIG1vcmUgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQgd2l0aG91dCB1c2luZyBjbGFzc0xpc3QuXG4gKiBJZiBhbnkgb2YgdGhlIGNsYXNzZXMgaXMgcHJlc2VudCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQsXG4gKiBvciBhZGRlZCBvdGhlcndpc2UuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHdoaWNoIGNsYXNzZXMgd2lsbCBiZSB0b2dnbGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgVGhlIGNsYXNzZXMgd2hpY2ggaGF2ZSB0byBhZGRlZCBvciByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVDbGFzc2VzV2l0aG91dE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRsZXQgZWxlbWVudENsYXNzTmFtZSA9IGAgJHtlbGVtZW50LmNsYXNzTmFtZX0gYDtcblxuXHRjbGFzc2VzID0gY2xhc3Nlcy5zcGxpdCgnICcpO1xuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgY2xhc3Nlcy5sZW5ndGg7IGkrKykge1xuXHRcdGNvbnN0IGNsYXNzTmFtZSA9IGAgJHtjbGFzc2VzW2ldfSBgO1xuXHRcdGNvbnN0IGNsYXNzSW5kZXggPSBlbGVtZW50Q2xhc3NOYW1lLmluZGV4T2YoY2xhc3NOYW1lKTtcblxuXHRcdGlmIChjbGFzc0luZGV4ID09PSAtMSkge1xuXHRcdFx0ZWxlbWVudENsYXNzTmFtZSA9IGAke2VsZW1lbnRDbGFzc05hbWV9JHtjbGFzc2VzW2ldfSBgO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBiZWZvcmUgPSBlbGVtZW50Q2xhc3NOYW1lLnN1YnN0cmluZygwLCBjbGFzc0luZGV4KTtcblx0XHRcdGNvbnN0IGFmdGVyID0gZWxlbWVudENsYXNzTmFtZS5zdWJzdHJpbmcoXG5cdFx0XHRcdGNsYXNzSW5kZXggKyBjbGFzc05hbWUubGVuZ3RoXG5cdFx0XHQpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0XHRlbGVtZW50Q2xhc3NOYW1lID0gYCR7YmVmb3JlfSAke2FmdGVyfWA7XG5cdFx0fVxuXHR9XG5cblx0ZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50Q2xhc3NOYW1lLnRyaW0oKTtcbn1cblxuLyoqXG4gKiBUcmlnZ2VycyBhbGwgbGlzdGVuZXJzIGZvciB0aGUgZ2l2ZW4gZXZlbnQgdHlwZSB0aGF0IGFyZSBzdG9yZWQgaW4gdGhlXG4gKiBzcGVjaWZpZWQgZWxlbWVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHBhcmFtIHshQXJyYXl9IGRlZmF1bHRGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogICAgIG9mIHJ1bm5pbmcgdGhlbS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlckVsZW1lbnRMaXN0ZW5lcnNfKGVsZW1lbnQsIGV2ZW50LCBkZWZhdWx0Rm5zKSB7XG5cdGNvbnN0IGxhc3RDb250YWluZXIgPSBldmVudFtMQVNUX0NPTlRBSU5FUl07XG5cdGlmICghaXNEZWYobGFzdENvbnRhaW5lcikgfHwgIWNvbnRhaW5zKGxhc3RDb250YWluZXIsIGVsZW1lbnQpKSB7XG5cdFx0Y29uc3QgbGlzdGVuZXJzID0gZG9tRGF0YS5nZXQoZWxlbWVudCwgJ2xpc3RlbmVycycsIHt9KVtldmVudC50eXBlXTtcblx0XHRyZXR1cm4gdHJpZ2dlckxpc3RlbmVyc18obGlzdGVuZXJzLCBldmVudCwgZWxlbWVudCwgZGVmYXVsdEZucyk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogVHJpZ2dlcnMgdGhlIHNwZWNpZmllZCBldmVudCBvbiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAqIE5PVEU6IFRoaXMgc2hvdWxkIG1vc3RseSBiZSB1c2VkIGZvciB0ZXN0aW5nLCBub3Qgb24gcmVhbCBjb2RlLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgbm9kZSB0aGF0IHNob3VsZCB0cmlnZ2VyIHRoZSBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGJlIHRyaWdncmVkLlxuICogQHBhcmFtIHtPYmplY3Q9fSBldmVudE9iaiBBbiBvYmplY3Qgd2l0aCBkYXRhIHRoYXQgc2hvdWxkIGJlIG9uIHRoZVxuICogICB0cmlnZ2VyZWQgZXZlbnQncyBwYXlsb2FkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJpZ2dlckV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgZXZlbnRPYmopIHtcblx0aWYgKGlzQWJsZVRvSW50ZXJhY3RXaXRoXyhlbGVtZW50LCBldmVudE5hbWUsIGV2ZW50T2JqKSkge1xuXHRcdGNvbnN0IHBheWxvYWQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnSFRNTEV2ZW50cycpO1xuXHRcdHBheWxvYWQuaW5pdEV2ZW50KGV2ZW50TmFtZSwgdHJ1ZSwgdHJ1ZSk7XG5cdFx0b2JqZWN0Lm1peGluKHBheWxvYWQsIGV2ZW50T2JqKTtcblx0XHRlbGVtZW50LmRpc3BhdGNoRXZlbnQocGF5bG9hZCk7XG5cdH1cbn1cblxuLyoqXG4gKiBUcmlnZ2VycyB0aGUgZ2l2ZW4gbGlzdGVuZXJzIGFycmF5LlxuICogQHBhcmFtIHtBcnJheTwhZnVuY3Rpb24oKT59IGxpc3RlbmVyc1xuICogQHBhcmFtIHshRXZlbnR9IGV2ZW50XG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0geyFBcnJheX0gZGVmYXVsdEZucyBBcnJheSB0byBjb2xsZWN0IGRlZmF1bHQgbGlzdGVuZXJzIGluLCBpbnN0ZWFkXG4gKiAgICAgb2YgcnVubmluZyB0aGVtLlxuICogQHJldHVybiB7Ym9vbGVhbn0gRmFsc2UgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSB0cmlnZ2VyZWQgY2FsbGJhY2tzIHJldHVybnNcbiAqICAgICBmYWxzZSwgb3IgdHJ1ZSBvdGhlcndpc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0cmlnZ2VyTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGV2ZW50LCBlbGVtZW50LCBkZWZhdWx0Rm5zKSB7XG5cdGxldCByZXQgPSB0cnVlO1xuXHRsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMgfHwgW107XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aCAmJiAhZXZlbnQuc3RvcHBlZEltbWVkaWF0ZTsgaSsrKSB7XG5cdFx0aWYgKGxpc3RlbmVyc1tpXS5kZWZhdWx0TGlzdGVuZXJfKSB7XG5cdFx0XHRkZWZhdWx0Rm5zLnB1c2goe1xuXHRcdFx0XHRlbGVtZW50LFxuXHRcdFx0XHRmbjogbGlzdGVuZXJzW2ldLFxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldCAmPSBsaXN0ZW5lcnNbaV0oZXZlbnQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFRyaWdnZXJzIGFsbCBzZWxlY3RvciBsaXN0ZW5lcnMgZm9yIHRoZSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGNvbnRhaW5lclxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHshRXZlbnR9IGV2ZW50XG4gKiBAcGFyYW0geyFBcnJheX0gZGVmYXVsdEZucyBBcnJheSB0byBjb2xsZWN0IGRlZmF1bHQgbGlzdGVuZXJzIGluLCBpbnN0ZWFkXG4gKiAgICAgb2YgcnVubmluZyB0aGVtLlxuICogQHJldHVybiB7Ym9vbGVhbn0gRmFsc2UgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSB0cmlnZ2VyZWQgY2FsbGJhY2tzIHJldHVybnNcbiAqICAgICBmYWxzZSwgb3IgdHJ1ZSBvdGhlcndpc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0cmlnZ2VyU2VsZWN0b3JMaXN0ZW5lcnNfKGNvbnRhaW5lciwgZWxlbWVudCwgZXZlbnQsIGRlZmF1bHRGbnMpIHtcblx0bGV0IHJldCA9IHRydWU7XG5cdGNvbnN0IGRhdGEgPSBkb21EYXRhLmdldChjb250YWluZXIsICdkZWxlZ2F0aW5nJywge30pO1xuXHRjb25zdCBtYXAgPSBkYXRhW2V2ZW50LnR5cGVdLnNlbGVjdG9ycztcblx0Y29uc3Qgc2VsZWN0b3JzID0gT2JqZWN0LmtleXMobWFwKTtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3RvcnMubGVuZ3RoICYmICFldmVudC5zdG9wcGVkSW1tZWRpYXRlOyBpKyspIHtcblx0XHRpZiAobWF0Y2goZWxlbWVudCwgc2VsZWN0b3JzW2ldKSkge1xuXHRcdFx0Y29uc3QgbGlzdGVuZXJzID0gbWFwW3NlbGVjdG9yc1tpXV07XG5cdFx0XHRyZXQgJj0gdHJpZ2dlckxpc3RlbmVyc18obGlzdGVuZXJzLCBldmVudCwgZWxlbWVudCwgZGVmYXVsdEZucyk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiByZXQ7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIFRoaXMgZmlsZSBleGlzdHMganVzdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIG1ha2luZyBzdXJlIHRoYXQgb2xkXG4vLyBkZWZhdWx0IGltcG9ydHMgZm9yIHRoaXMgZmlsZSBzdGlsbCB3b3JrLiBJdCdzIGJlc3QgdG8gdXNlIHRoZSBuYW1lZCBleHBvcnRzXG4vLyBmb3IgZWFjaCBmdW5jdGlvbiBpbnN0ZWFkIHRob3VnaCwgc2luY2UgdGhhdCBhbGxvd3MgYnVuZGxlcnMgbGlrZSBSb2xsdXAgdG9cbi8vIHJlZHVjZSB0aGUgYnVuZGxlIHNpemUgYnkgcmVtb3ZpbmcgdW51c2VkIGNvZGUuXG5pbXBvcnQgKiBhcyBkb20gZnJvbSAnLi9kb21OYW1lZCc7XG5cbmV4cG9ydCBkZWZhdWx0IGRvbTtcbmV4cG9ydCB7ZG9tfTtcbmV4cG9ydCAqIGZyb20gJy4vZG9tTmFtZWQnO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2RlbGVnYXRlLCBvbiwgc3VwcG9ydHNFdmVudH0gZnJvbSAnLi9kb20nO1xuaW1wb3J0IHtFdmVudEVtaXR0ZXJQcm94eX0gZnJvbSAnbWV0YWwtZXZlbnRzJztcblxuLyoqXG4gKiBEb21FdmVudEVtaXR0ZXJQcm94eSB1dGlsaXR5LiBJdCBleHRlbmRzIGBFdmVudEVtaXR0ZXJQcm94eWAgdG8gYWxzbyBhY2NlcHRcbiAqIGRvbSBlbGVtZW50cyBhcyBvcmlnaW4gZW1pdHRlcnMuXG4gKiBAZXh0ZW5kcyB7RXZlbnRFbWl0dGVyUHJveHl9XG4gKi9cbmNsYXNzIERvbUV2ZW50RW1pdHRlclByb3h5IGV4dGVuZHMgRXZlbnRFbWl0dGVyUHJveHkge1xuXHQvKipcblx0ICogQWRkcyB0aGUgZ2l2ZW4gbGlzdGVuZXIgZm9yIHRoZSBnaXZlbiBldmVudC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gVGhlIGxpc3RlbmVkIGV2ZW50J3MgaGFuZGxlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0YWRkTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdGlmICh0aGlzLm9yaWdpbkVtaXR0ZXJfLmFkZEV2ZW50TGlzdGVuZXIpIHtcblx0XHRcdGlmICh0aGlzLmlzRGVsZWdhdGVFdmVudF8oZXZlbnQpKSB7XG5cdFx0XHRcdGNvbnN0IGluZGV4ID0gZXZlbnQuaW5kZXhPZignOicsIDkpO1xuXHRcdFx0XHRjb25zdCBldmVudE5hbWUgPSBldmVudC5zdWJzdHJpbmcoOSwgaW5kZXgpO1xuXHRcdFx0XHRjb25zdCBzZWxlY3RvciA9IGV2ZW50LnN1YnN0cmluZyhpbmRleCArIDEpO1xuXHRcdFx0XHRyZXR1cm4gZGVsZWdhdGUoXG5cdFx0XHRcdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyxcblx0XHRcdFx0XHRldmVudE5hbWUsXG5cdFx0XHRcdFx0c2VsZWN0b3IsXG5cdFx0XHRcdFx0bGlzdGVuZXJcblx0XHRcdFx0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIG9uKHRoaXMub3JpZ2luRW1pdHRlcl8sIGV2ZW50LCBsaXN0ZW5lcik7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBzdXBlci5hZGRMaXN0ZW5lcl8oZXZlbnQsIGxpc3RlbmVyKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBpcyBvZiB0aGUgZGVsZWdhdGUgdHlwZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGlzRGVsZWdhdGVFdmVudF8oZXZlbnQpIHtcblx0XHRyZXR1cm4gZXZlbnQuc3Vic3RyKDAsIDkpID09PSAnZGVsZWdhdGU6Jztcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGV2ZW50IGlzIHN1cHBvcnRlZCBieSB0aGUgb3JpZ2luIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRpc1N1cHBvcnRlZERvbUV2ZW50XyhldmVudCkge1xuXHRcdGlmICghdGhpcy5vcmlnaW5FbWl0dGVyXyB8fCAhdGhpcy5vcmlnaW5FbWl0dGVyXy5hZGRFdmVudExpc3RlbmVyKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIChcblx0XHRcdCh0aGlzLmlzRGVsZWdhdGVFdmVudF8oZXZlbnQpICYmIGV2ZW50LmluZGV4T2YoJzonLCA5KSAhPT0gLTEpIHx8XG5cdFx0XHRzdXBwb3J0c0V2ZW50KHRoaXMub3JpZ2luRW1pdHRlcl8sIGV2ZW50KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBzaG91bGQgYmUgcHJveGllZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRzaG91bGRQcm94eUV2ZW50XyhldmVudCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHRzdXBlci5zaG91bGRQcm94eUV2ZW50XyhldmVudCkgJiYgdGhpcy5pc1N1cHBvcnRlZERvbUV2ZW50XyhldmVudClcblx0XHQpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRG9tRXZlbnRFbWl0dGVyUHJveHk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXBwZW5kfSBmcm9tICcuL2RvbSc7XG5pbXBvcnQge3N0cmluZ30gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIENsYXNzIHdpdGggc3RhdGljIG1ldGhvZHMgcmVzcG9uc2libGUgZm9yIGRvaW5nIGJyb3dzZXIgZmVhdHVyZSBjaGVja3MuXG4gKi9cbmNsYXNzIGZlYXR1cmVzIHtcblx0LyoqXG5cdCAqIFNvbWUgYnJvd3NlcnMgc3RpbGwgc3VwcG9ydHMgcHJlZml4ZWQgYW5pbWF0aW9uIGV2ZW50cy4gVGhpcyBtZXRob2QgY2FuXG5cdCAqIGJlIHVzZWQgdG8gcmV0cmlldmUgdGhlIGN1cnJlbnQgYnJvd3NlciBldmVudCBuYW1lIGZvciBib3RoLCBhbmltYXRpb25cblx0ICogYW5kIHRyYW5zaXRpb24uXG5cdCAqIEByZXR1cm4ge29iamVjdH1cblx0ICovXG5cdHN0YXRpYyBjaGVja0FuaW1hdGlvbkV2ZW50TmFtZSgpIHtcblx0XHRpZiAoZmVhdHVyZXMuYW5pbWF0aW9uRXZlbnROYW1lXyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRmZWF0dXJlcy5hbmltYXRpb25FdmVudE5hbWVfID0ge1xuXHRcdFx0XHRhbmltYXRpb246IGZlYXR1cmVzLmNoZWNrQW5pbWF0aW9uRXZlbnROYW1lXygnYW5pbWF0aW9uJyksXG5cdFx0XHRcdHRyYW5zaXRpb246IGZlYXR1cmVzLmNoZWNrQW5pbWF0aW9uRXZlbnROYW1lXygndHJhbnNpdGlvbicpLFxuXHRcdFx0fTtcblx0XHR9XG5cdFx0cmV0dXJuIGZlYXR1cmVzLmFuaW1hdGlvbkV2ZW50TmFtZV87XG5cdH1cblxuXHQvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUeXBlIHRvIHRlc3Q6IGFuaW1hdGlvbiwgdHJhbnNpdGlvbi5cblx0ICogQHJldHVybiB7c3RyaW5nfSBCcm93c2VyIGV2ZW50IG5hbWUuXG5cdCAqL1xuXHRzdGF0aWMgY2hlY2tBbmltYXRpb25FdmVudE5hbWVfKHR5cGUpIHtcblx0XHRjb25zdCBwcmVmaXhlcyA9IFsnV2Via2l0JywgJ01TJywgJ08nLCAnJ107XG5cdFx0Y29uc3QgdHlwZVRpdGxlQ2FzZSA9IHN0cmluZy5yZXBsYWNlSW50ZXJ2YWwoXG5cdFx0XHR0eXBlLFxuXHRcdFx0MCxcblx0XHRcdDEsXG5cdFx0XHR0eXBlLnN1YnN0cmluZygwLCAxKS50b1VwcGVyQ2FzZSgpXG5cdFx0KTtcblx0XHRjb25zdCBzdWZmaXhlcyA9IFtcblx0XHRcdGAke3R5cGVUaXRsZUNhc2V9RW5kYCxcblx0XHRcdGAke3R5cGVUaXRsZUNhc2V9RW5kYCxcblx0XHRcdGAke3R5cGVUaXRsZUNhc2V9RW5kYCxcblx0XHRcdGAke3R5cGV9ZW5kYCxcblx0XHRdO1xuXHRcdGlmICghZmVhdHVyZXMuYW5pbWF0aW9uRWxlbWVudF8pIHtcblx0XHRcdGZlYXR1cmVzLmFuaW1hdGlvbkVsZW1lbnRfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgcHJlZml4ZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChcblx0XHRcdFx0ZmVhdHVyZXMuYW5pbWF0aW9uRWxlbWVudF8uc3R5bGVbXG5cdFx0XHRcdFx0cHJlZml4ZXNbaV0gKyB0eXBlVGl0bGVDYXNlXG5cdFx0XHRcdF0gIT09IHVuZGVmaW5lZCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0XHQpIHtcblx0XHRcdFx0cmV0dXJuIHByZWZpeGVzW2ldLnRvTG93ZXJDYXNlKCkgKyBzdWZmaXhlc1tpXTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGAke3R5cGV9ZW5kYDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTb21lIGJyb3dzZXJzIChsaWtlIElFMTEsIEVkZ2UpIGNoYW5nZSB0aGUgb3JkZXIgb2YgZWxlbWVudCBhdHRyaWJ1dGVzLCB3aGVuIGh0bWxcblx0ICogaXMgcmVuZGVyZWQuIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNoZWNrIGlmIHRoaXMgYmVoYXZpb3IgaGFwcGVucyBvblxuXHQgKiB0aGUgY3VycmVudCBicm93c2VyLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGNoZWNrQXR0ck9yZGVyQ2hhbmdlKCkge1xuXHRcdGlmIChmZWF0dXJlcy5hdHRyT3JkZXJDaGFuZ2VfID09PSB1bmRlZmluZWQpIHtcblx0XHRcdGNvbnN0IG9yaWdpbmFsQ29udGVudCA9ICc8ZGl2IGRhdGEtY29tcG9uZW50PVwiXCIgZGF0YS1yZWY9XCJcIj48L2Rpdj4nO1xuXHRcdFx0Y29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0YXBwZW5kKGVsZW1lbnQsIG9yaWdpbmFsQ29udGVudCk7XG5cdFx0XHRmZWF0dXJlcy5hdHRyT3JkZXJDaGFuZ2VfID0gb3JpZ2luYWxDb250ZW50ICE9PSBlbGVtZW50LmlubmVySFRNTDtcblx0XHR9XG5cdFx0cmV0dXJuIGZlYXR1cmVzLmF0dHJPcmRlckNoYW5nZV87XG5cdH1cbn1cblxuZmVhdHVyZXMuYW5pbWF0aW9uRWxlbWVudF8gPSB1bmRlZmluZWQ7XG5mZWF0dXJlcy5hbmltYXRpb25FdmVudE5hbWVfID0gdW5kZWZpbmVkO1xuZmVhdHVyZXMuYXR0ck9yZGVyQ2hhbmdlXyA9IHVuZGVmaW5lZDtcblxuZXhwb3J0IGRlZmF1bHQgZmVhdHVyZXM7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXN5bmN9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7ZXhpdERvY3VtZW50LCBvbmNlfSBmcm9tICcuL2RvbSc7XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIHJ1bm5pbmcgamF2YXNjcmlwdCBjb2RlIGluIHRoZSBnbG9iYWwgc2NvcGUuXG4gKi9cbmNsYXNzIGdsb2JhbEV2YWwge1xuXHQvKipcblx0ICogRXZhbHVhdGVzIHRoZSBnaXZlbiBzdHJpbmcgaW4gdGhlIGdsb2JhbCBzY29wZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc2NyaXB0XG5cdCAqL1xuXHRzdGF0aWMgcnVuKHRleHQsIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cdFx0c2NyaXB0LnRleHQgPSB0ZXh0O1xuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc2NyaXB0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH1cblx0XHRleGl0RG9jdW1lbnQoc2NyaXB0KTtcblx0XHRyZXR1cm4gc2NyaXB0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gamF2YXNjcmlwdCBmaWxlIGluIHRoZSBnbG9iYWwgc2NvcGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgVGhlIGZpbGUncyBwYXRoLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc2NyaXB0XG5cdCAqL1xuXHRzdGF0aWMgcnVuRmlsZShzcmMsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRzY3JpcHQuc3JjID0gc3JjO1xuXG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGV4aXREb2N1bWVudChzY3JpcHQpO1xuXHRcdFx0ZGVmYXVsdEZuICYmIGRlZmF1bHRGbigpO1xuXHRcdH07XG5cdFx0b25jZShzY3JpcHQsICdsb2FkJywgY2FsbGJhY2spO1xuXHRcdG9uY2Uoc2NyaXB0LCAnZXJyb3InLCBjYWxsYmFjayk7XG5cblx0XHRpZiAoYXBwZW5kRm4pIHtcblx0XHRcdGFwcGVuZEZuKHNjcmlwdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc2NyaXB0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgY29kZSByZWZlcmVuY2VkIGJ5IHRoZSBnaXZlbiBzY3JpcHQgZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gc2NyaXB0XG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWRcblx0ICogICB3aGVuIHRoZSBzY3JpcHQgaGFzIGJlZW4gcnVuLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzY3JpcHRcblx0ICovXG5cdHN0YXRpYyBydW5TY3JpcHQoc2NyaXB0LCBkZWZhdWx0Rm4sIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGRlZmF1bHRGbiAmJiBkZWZhdWx0Rm4oKTtcblx0XHR9O1xuXHRcdGlmIChzY3JpcHQudHlwZSAmJiBzY3JpcHQudHlwZSAhPT0gJ3RleHQvamF2YXNjcmlwdCcpIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGNhbGxiYWNrKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZXhpdERvY3VtZW50KHNjcmlwdCk7XG5cdFx0aWYgKHNjcmlwdC5zcmMpIHtcblx0XHRcdHJldHVybiBnbG9iYWxFdmFsLnJ1bkZpbGUoc2NyaXB0LnNyYywgZGVmYXVsdEZuLCBhcHBlbmRGbik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGNhbGxiYWNrKTtcblx0XHRcdHJldHVybiBnbG9iYWxFdmFsLnJ1bihzY3JpcHQudGV4dCwgYXBwZW5kRm4pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgYW55IHNjcmlwdCB0YWdzIHByZXNlbnQgaW4gdGhlIGdpdmVuIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiAgIHdoZW4gdGhlIHNjcmlwdCBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU2NyaXB0c0luRWxlbWVudChlbGVtZW50LCBkZWZhdWx0Rm4sIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc2NyaXB0cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnc2NyaXB0Jyk7XG5cdFx0aWYgKHNjcmlwdHMubGVuZ3RoKSB7XG5cdFx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdHNJbk9yZGVyKHNjcmlwdHMsIDAsIGRlZmF1bHRGbiwgYXBwZW5kRm4pO1xuXHRcdH0gZWxzZSBpZiAoZGVmYXVsdEZuKSB7XG5cdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSdW5zIHRoZSBnaXZlbiBzY3JpcHRzIGVsZW1lbnRzIGluIHRoZSBvcmRlciB0aGF0IHRoZXkgYXBwZWFyLlxuXHQgKiBAcGFyYW0geyFOb2RlTGlzdH0gc2NyaXB0c1xuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiAgIHdoZW4gdGhlIHNjcmlwdCBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU2NyaXB0c0luT3JkZXIoc2NyaXB0cywgaW5kZXgsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdChcblx0XHRcdHNjcmlwdHMuaXRlbShpbmRleCksXG5cdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKGluZGV4IDwgc2NyaXB0cy5sZW5ndGggLSAxKSB7XG5cdFx0XHRcdFx0Z2xvYmFsRXZhbC5ydW5TY3JpcHRzSW5PcmRlcihcblx0XHRcdFx0XHRcdHNjcmlwdHMsXG5cdFx0XHRcdFx0XHRpbmRleCArIDEsXG5cdFx0XHRcdFx0XHRkZWZhdWx0Rm4sXG5cdFx0XHRcdFx0XHRhcHBlbmRGblxuXHRcdFx0XHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdFx0fSBlbHNlIGlmIChkZWZhdWx0Rm4pIHtcblx0XHRcdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0YXBwZW5kRm5cblx0XHQpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGdsb2JhbEV2YWw7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXN5bmN9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7b25jZX0gZnJvbSAnLi9kb20nO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zIGZvciBydW5uaW5nIHN0eWxlcy5cbiAqL1xuY2xhc3MgZ2xvYmFsRXZhbFN0eWxlcyB7XG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdGhlIGdpdmVuIHN0eWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzdHlsZVxuXHQgKi9cblx0c3RhdGljIHJ1bih0ZXh0LCBhcHBlbmRGbikge1xuXHRcdGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblx0XHRzdHlsZS5pbm5lckhUTUwgPSB0ZXh0O1xuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc3R5bGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblx0XHR9XG5cdFx0cmV0dXJuIHN0eWxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gc3R5bGUgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgVGhlIGZpbGUncyBwYXRoLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc3R5bGVzIGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc3R5bGVcblx0ICovXG5cdHN0YXRpYyBydW5GaWxlKGhyZWYsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGluaycpO1xuXHRcdGxpbmsucmVsID0gJ3N0eWxlc2hlZXQnO1xuXHRcdGxpbmsuaHJlZiA9IGhyZWY7XG5cdFx0Z2xvYmFsRXZhbFN0eWxlcy5ydW5TdHlsZShsaW5rLCBkZWZhdWx0Rm4sIGFwcGVuZEZuKTtcblx0XHRyZXR1cm4gbGluaztcblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdGhlIGNvZGUgcmVmZXJlbmNlZCBieSB0aGUgZ2l2ZW4gc3R5bGUvbGluayBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBzdHlsZVxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogIEByZXR1cm4ge0VsZW1lbnR9IHN0eWxlXG5cdCAqL1xuXHRzdGF0aWMgcnVuU3R5bGUoc3R5bGUsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGVmYXVsdEZuICYmIGRlZmF1bHRGbigpO1xuXHRcdH07XG5cdFx0aWYgKFxuXHRcdFx0c3R5bGUucmVsICYmXG5cdFx0XHRzdHlsZS5yZWwgIT09ICdzdHlsZXNoZWV0JyAmJlxuXHRcdFx0c3R5bGUucmVsICE9PSAnY2Fub25pY2FsJyAmJlxuXHRcdFx0c3R5bGUucmVsICE9PSAnYWx0ZXJuYXRlJ1xuXHRcdCkge1xuXHRcdFx0YXN5bmMubmV4dFRpY2soY2FsbGJhY2spO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChcblx0XHRcdHN0eWxlLnRhZ05hbWUgPT09ICdTVFlMRScgfHxcblx0XHRcdHN0eWxlLnJlbCA9PT0gJ2Nhbm9uaWNhbCcgfHxcblx0XHRcdHN0eWxlLnJlbCA9PT0gJ2FsdGVybmF0ZSdcblx0XHQpIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGNhbGxiYWNrKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b25jZShzdHlsZSwgJ2xvYWQnLCBjYWxsYmFjayk7XG5cdFx0XHRvbmNlKHN0eWxlLCAnZXJyb3InLCBjYWxsYmFjayk7XG5cdFx0fVxuXG5cdFx0aWYgKGFwcGVuZEZuKSB7XG5cdFx0XHRhcHBlbmRGbihzdHlsZSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuXHRcdH1cblxuXHRcdHJldHVybiBzdHlsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgYW55IHN0eWxlIHByZXNlbnQgaW4gdGhlIGdpdmVuIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZVxuXHQgKiAgIHN0eWxlIGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICovXG5cdHN0YXRpYyBydW5TdHlsZXNJbkVsZW1lbnQoZWxlbWVudCwgZGVmYXVsdEZuLCBhcHBlbmRGbikge1xuXHRcdGNvbnN0IHN0eWxlcyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnc3R5bGUsbGluaycpO1xuXHRcdGlmIChzdHlsZXMubGVuZ3RoID09PSAwICYmIGRlZmF1bHRGbikge1xuXHRcdFx0YXN5bmMubmV4dFRpY2soZGVmYXVsdEZuKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRsZXQgbG9hZENvdW50ID0gMDtcblx0XHRjb25zdCBjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKGRlZmF1bHRGbiAmJiArK2xvYWRDb3VudCA9PT0gc3R5bGVzLmxlbmd0aCkge1xuXHRcdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzdHlsZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGdsb2JhbEV2YWxTdHlsZXMucnVuU3R5bGUoc3R5bGVzW2ldLCBjYWxsYmFjaywgYXBwZW5kRm4pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBnbG9iYWxFdmFsU3R5bGVzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2lzU2VydmVyU2lkZX0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHtyZWdpc3RlckN1c3RvbUV2ZW50LCBjb250YWluc30gZnJvbSAnLi9kb20nO1xuaW1wb3J0IGZlYXR1cmVzIGZyb20gJy4vZmVhdHVyZXMnO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGN1c3RvbSBldmVudHMgZm9yIGV2ZW50IGRlbGVnYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyRXZlbnRzKCkge1xuXHRjb25zdCBtb3VzZUV2ZW50TWFwID0ge1xuXHRcdG1vdXNlZW50ZXI6ICdtb3VzZW92ZXInLFxuXHRcdG1vdXNlbGVhdmU6ICdtb3VzZW91dCcsXG5cdFx0cG9pbnRlcmVudGVyOiAncG9pbnRlcm92ZXInLFxuXHRcdHBvaW50ZXJsZWF2ZTogJ3BvaW50ZXJvdXQnLFxuXHR9O1xuXHRPYmplY3Qua2V5cyhtb3VzZUV2ZW50TWFwKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50TmFtZSkge1xuXHRcdHJlZ2lzdGVyQ3VzdG9tRXZlbnQoZXZlbnROYW1lLCB7XG5cdFx0XHRkZWxlZ2F0ZTogdHJ1ZSxcblx0XHRcdGhhbmRsZXI6IGZ1bmN0aW9uKGNhbGxiYWNrLCBldmVudCkge1xuXHRcdFx0XHRjb25zdCByZWxhdGVkID0gZXZlbnQucmVsYXRlZFRhcmdldDtcblx0XHRcdFx0Y29uc3QgdGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQ7XG5cdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0IXJlbGF0ZWQgfHxcblx0XHRcdFx0XHQocmVsYXRlZCAhPT0gdGFyZ2V0ICYmICFjb250YWlucyh0YXJnZXQsIHJlbGF0ZWQpKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRldmVudC5jdXN0b21UeXBlID0gZXZlbnROYW1lO1xuXHRcdFx0XHRcdHJldHVybiBjYWxsYmFjayhldmVudCk7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRvcmlnaW5hbEV2ZW50OiBtb3VzZUV2ZW50TWFwW2V2ZW50TmFtZV0sXG5cdFx0fSk7XG5cdH0pO1xuXG5cdGNvbnN0IGFuaW1hdGlvbkV2ZW50TWFwID0ge1xuXHRcdGFuaW1hdGlvbjogJ2FuaW1hdGlvbmVuZCcsXG5cdFx0dHJhbnNpdGlvbjogJ3RyYW5zaXRpb25lbmQnLFxuXHR9O1xuXHRPYmplY3Qua2V5cyhhbmltYXRpb25FdmVudE1hcCkuZm9yRWFjaChmdW5jdGlvbihldmVudFR5cGUpIHtcblx0XHRjb25zdCBldmVudE5hbWUgPSBhbmltYXRpb25FdmVudE1hcFtldmVudFR5cGVdO1xuXHRcdHJlZ2lzdGVyQ3VzdG9tRXZlbnQoZXZlbnROYW1lLCB7XG5cdFx0XHRldmVudDogdHJ1ZSxcblx0XHRcdGRlbGVnYXRlOiB0cnVlLFxuXHRcdFx0aGFuZGxlcjogZnVuY3Rpb24oY2FsbGJhY2ssIGV2ZW50KSB7XG5cdFx0XHRcdGV2ZW50LmN1c3RvbVR5cGUgPSBldmVudE5hbWU7XG5cdFx0XHRcdHJldHVybiBjYWxsYmFjayhldmVudCk7XG5cdFx0XHR9LFxuXHRcdFx0b3JpZ2luYWxFdmVudDogZmVhdHVyZXMuY2hlY2tBbmltYXRpb25FdmVudE5hbWUoKVtldmVudFR5cGVdLFxuXHRcdH0pO1xuXHR9KTtcbn1cblxuaWYgKCFpc1NlcnZlclNpZGUoKSkge1xuXHRyZWdpc3RlckV2ZW50cygpO1xufVxuIiwidmFyIGdsb2JhbHMgPSBnbG9iYWxzIHx8IHt9O1xuXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0Z2xvYmFscy53aW5kb3cgPSB3aW5kb3c7XG59XG5cbmlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG5cdGdsb2JhbHMuZG9jdW1lbnQgPSBkb2N1bWVudDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZ2xvYmFscztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBBIGNvbGxlY3Rpb24gb2YgY29yZSB1dGlsaXR5IGZ1bmN0aW9ucy5cbiAqIEBjb25zdFxuICovXG5cbmxldCBjb21wYXRpYmlsaXR5TW9kZURhdGFfO1xuXG4vKipcbiAqIENvdW50ZXIgZm9yIHVuaXF1ZSBpZC5cbiAqIEB0eXBlIHtOdW1iZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG5sZXQgdW5pcXVlSWRDb3VudGVyXyA9IDE7XG5cbi8qKlxuICogVW5pcXVlIGlkIHByb3BlcnR5IHByZWZpeC5cbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAcHJvdGVjdGVkXG4gKi9cbmV4cG9ydCBjb25zdCBVSURfUFJPUEVSVFkgPSBgY29yZV8keyhNYXRoLnJhbmRvbSgpICogMWU5KSA+Pj4gMH1gO1xuXG4vKipcbiAqIFdoZW4gZGVmaW5pbmcgYSBjbGFzcyBGb28gd2l0aCBhbiBhYnN0cmFjdCBtZXRob2QgYmFyKCksIHlvdSBjYW4gZG86XG4gKiBGb28ucHJvdG90eXBlLmJhciA9IGFic3RyYWN0TWV0aG9kXG4gKlxuICogTm93IGlmIGEgc3ViY2xhc3Mgb2YgRm9vIGZhaWxzIHRvIG92ZXJyaWRlIGJhcigpLCBhbiBlcnJvciB3aWxsIGJlIHRocm93blxuICogd2hlbiBiYXIoKSBpcyBpbnZva2VkLlxuICpcbiAqIEB0eXBlIHshRnVuY3Rpb259XG4gKiBAdGhyb3dzIHtFcnJvcn0gd2hlbiBpbnZva2VkIHRvIGluZGljYXRlIHRoZSBtZXRob2Qgc2hvdWxkIGJlIG92ZXJyaWRkZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhYnN0cmFjdE1ldGhvZCgpIHtcblx0dGhyb3cgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgYWJzdHJhY3QgbWV0aG9kJyk7XG59XG5cbi8qKlxuICogRGlzYWJsZXMgTWV0YWwuanMncyBjb21wYXRpYmlsaXR5IG1vZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNhYmxlQ29tcGF0aWJpbGl0eU1vZGUoKSB7XG5cdGNvbXBhdGliaWxpdHlNb2RlRGF0YV8gPSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRW5hYmxlcyBNZXRhbC5qcydzIGNvbXBhdGliaWxpdHkgbW9kZSB3aXRoIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgZnJvbSByY1xuICogYW5kIDEueCB2ZXJzaW9uczpcbiAqICAgICAtIFVzaW5nIFwia2V5XCIgdG8gcmVmZXJlbmNlIGNvbXBvbmVudCBpbnN0YW5jZXMuIEluIHRoZSBjdXJyZW50IHZlcnNpb25cbiAqICAgICAgIHRoaXMgc2hvdWxkIGJlIGRvbmUgdmlhIFwicmVmXCIgaW5zdGVhZC4gVGhpcyBhbGxvd3Mgb2xkIGNvZGUgc3RpbGxcbiAqICAgICAgIHVzaW5nIFwia2V5XCIgdG8ga2VlcCB3b3JraW5nIGxpa2UgYmVmb3JlLiBOT1RFOiB0aGlzIG1heSBjYXVzZVxuICogICAgICAgcHJvYmxlbXMsIHNpbmNlIFwia2V5XCIgaXMgbWVhbnQgdG8gYmUgdXNlZCBkaWZmZXJlbnRseS4gT25seSB1c2UgdGhpc1xuICogICAgICAgaWYgaXQncyBub3QgcG9zc2libGUgdG8gdXBncmFkZSB0aGUgY29kZSB0byB1c2UgXCJyZWZcIiBpbnN0ZWFkLlxuICogQHBhcmFtIHtPYmplY3Q9fSBkYXRhIE9wdGlvbmFsIG9iamVjdCB3aXRoIGRhdGEgdG8gc3BlY2lmeSBtb3JlXG4gKiAgICAgZGV0YWlscywgc3VjaCBhczpcbiAqICAgICAgICAgLSByZW5kZXJlcnMge0FycmF5fSB0aGUgdGVtcGxhdGUgcmVuZGVyZXJzIHRoYXQgc2hvdWxkIGJlIGluXG4gKiAgICAgICAgICAgY29tcGF0aWJpbGl0eSBtb2RlLCBlaXRoZXIgdGhlaXIgY29uc3RydWN0b3JzIG9yIHN0cmluZ3NcbiAqICAgICAgICAgICByZXByZXNlbnRpbmcgdGhlbSAoZS5nLiAnc295JyBvciAnanN4JykuIEJ5IGRlZmF1bHQsIGFsbCB0aGUgb25lc1xuICogICAgICAgICAgIHRoYXQgZXh0ZW5kIGZyb20gSW5jcmVtZW50YWxEb21SZW5kZXJlci5cbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmFibGVDb21wYXRpYmlsaXR5TW9kZShkYXRhID0ge30pIHtcblx0Y29tcGF0aWJpbGl0eU1vZGVEYXRhXyA9IGRhdGE7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZGF0YSB1c2VkIGZvciBjb21wYXRpYmlsaXR5IG1vZGUsIG9yIG5vdGhpbmcgaWYgaXQgaGFzbid0IGJlZW5cbiAqIGVuYWJsZWQuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb21wYXRpYmlsaXR5TW9kZURhdGEoKSB7XG5cdC8vIENvbXBhdGliaWxpdHkgbW9kZSBjYW4gYmUgc2V0IHZpYSB0aGUgX19NRVRBTF9DT01QQVRJQklMSVRZX18gZ2xvYmFsIHZhci5cblx0aWYgKGNvbXBhdGliaWxpdHlNb2RlRGF0YV8gPT09IHVuZGVmaW5lZCkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuX19NRVRBTF9DT01QQVRJQklMSVRZX18pIHtcblx0XHRcdGVuYWJsZUNvbXBhdGliaWxpdHlNb2RlKHdpbmRvdy5fX01FVEFMX0NPTVBBVElCSUxJVFlfXyk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBjb21wYXRpYmlsaXR5TW9kZURhdGFfO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGlmIGl0J3MgdHJ1dGh5LCBvciB0aGUgc2Vjb25kIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7Kn0gYVxuICogQHBhcmFtIHsqfSBiXG4gKiBAcmV0dXJuIHsqfVxuICogQHByb3RlY3RlZFxuICovXG5mdW5jdGlvbiBnZXRGaXJzdFRydXRoeV8oYSwgYikge1xuXHRyZXR1cm4gYSB8fCBiO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGdpdmVuIGZ1bmN0aW9uLiBJZiB0aGUgY3VycmVudCBicm93c2VyIGRvZXNuJ3RcbiAqIHN1cHBvcnQgdGhlIGBuYW1lYCBwcm9wZXJ0eSwgdGhpcyB3aWxsIGNhbGN1bGF0ZSBpdCBmcm9tIHRoZSBmdW5jdGlvbidzXG4gKiBjb250ZW50IHN0cmluZy5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGZuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoZm4pIHtcblx0aWYgKCFmbi5uYW1lKSB7XG5cdFx0Y29uc3Qgc3RyID0gZm4udG9TdHJpbmcoKTtcblx0XHRmbi5uYW1lID0gc3RyLnN1YnN0cmluZyg5LCBzdHIuaW5kZXhPZignKCcpKTtcblx0fVxuXHRyZXR1cm4gZm4ubmFtZTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHN0YXRpYyBwcm9wZXJ0eSBpbiB0aGUgZ2l2ZW4gY2xhc3MuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gKiBpbmhlcml0ZWQgZnJvbSBhbmNlc3RvcnMgYXMgZXhwZWN0ZWQsIHVubGVzcyBhIGN1c3RvbSBtZXJnZSBmdW5jdGlvbiBpcyBnaXZlbixcbiAqIHdoaWNoIGNhbiBjaGFuZ2UgaG93IHRoZSBzdXBlciBjbGFzc2VzJyB2YWx1ZSBmb3IgdGhhdCBwcm9wZXJ0eSB3aWxsIGJlIG1lcmdlZFxuICogdG9nZXRoZXIuXG4gKiBUaGUgZmluYWwgbWVyZ2VkIHZhbHVlIHdpbGwgYmUgc3RvcmVkIGluIGFub3RoZXIgcHJvcGVydHksIHNvIHRoYXQgaXQgd29uJ3RcbiAqIGJlIHJlY2FsY3VsYXRlZCBldmVuIGlmIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG11bHRpcGxlIHRpbWVzLlxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gY3RvciBDbGFzcyBjb25zdHJ1Y3Rvci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWUgUHJvcGVydHkgbmFtZSB0byBiZSBtZXJnZWQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosICopOio9fSBtZXJnZUZuIEZ1bmN0aW9uIHRoYXQgcmVjZWl2ZXMgdGhlIG1lcmdlZFxuICogICAgIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBzbyBmYXIgYW5kIHRoZSBuZXh0IHZhbHVlIHRvIGJlIG1lcmdlZCB0byBpdC5cbiAqICAgICBTaG91bGQgcmV0dXJuIHRoZXNlIHR3byBtZXJnZWQgdG9nZXRoZXIuIElmIG5vdCBwYXNzZWQgdGhlIGZpbmFsIHByb3BlcnR5XG4gKiAgICAgd2lsbCBiZSB0aGUgZmlyc3QgdHJ1dGh5IHZhbHVlIGFtb25nIGFuY2VzdG9ycy5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0YXRpY1Byb3BlcnR5KFxuXHRjdG9yLFxuXHRwcm9wZXJ0eU5hbWUsXG5cdG1lcmdlRm4gPSBnZXRGaXJzdFRydXRoeV9cbikge1xuXHRjb25zdCBtZXJnZWROYW1lID0gcHJvcGVydHlOYW1lICsgJ19NRVJHRUQnO1xuXHRpZiAoIWN0b3IuaGFzT3duUHJvcGVydHkobWVyZ2VkTmFtZSkpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRsZXQgbWVyZ2VkID0gY3Rvci5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpXG5cdFx0XHQ/IGN0b3JbcHJvcGVydHlOYW1lXVxuXHRcdFx0OiBudWxsO1xuXHRcdGlmIChjdG9yLl9fcHJvdG9fXyAmJiAhY3Rvci5fX3Byb3RvX18uaXNQcm90b3R5cGVPZihGdW5jdGlvbikpIHtcblx0XHRcdG1lcmdlZCA9IG1lcmdlRm4oXG5cdFx0XHRcdG1lcmdlZCxcblx0XHRcdFx0Z2V0U3RhdGljUHJvcGVydHkoY3Rvci5fX3Byb3RvX18sIHByb3BlcnR5TmFtZSwgbWVyZ2VGbilcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGN0b3JbbWVyZ2VkTmFtZV0gPSBtZXJnZWQ7XG5cdH1cblx0cmV0dXJuIGN0b3JbbWVyZ2VkTmFtZV07XG59XG5cbi8qKlxuICogR2V0cyBhbiB1bmlxdWUgaWQuIElmIGBvYmplY3RgIGFyZ3VtZW50IGlzIHBhc3NlZCwgdGhlIG9iamVjdCBpc1xuICogbXV0YXRlZCB3aXRoIGFuIHVuaXF1ZSBpZC4gQ29uc2VjdXRpdmUgY2FsbHMgd2l0aCB0aGUgc2FtZSBvYmplY3RcbiAqIHJlZmVyZW5jZSB3b24ndCBtdXRhdGUgdGhlIG9iamVjdCBhZ2FpbiwgaW5zdGVhZCB0aGUgY3VycmVudCBvYmplY3QgdWlkXG4gKiByZXR1cm5zLiBTZWUge0BsaW5rIFVJRF9QUk9QRVJUWX0uXG4gKiBAcGFyYW0ge09iamVjdD19IG9iamVjdCBPcHRpb25hbCBvYmplY3QgdG8gYmUgbXV0YXRlZCB3aXRoIHRoZSB1aWQuIElmXG4gKiAgICAgbm90IHNwZWNpZmllZCB0aGlzIG1ldGhvZCBvbmx5IHJldHVybnMgdGhlIHVpZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vSW5oZXJpdGFuY2UgT3B0aW9uYWwgZmxhZyBpbmRpY2F0aW5nIGlmIHRoaXNcbiAqICAgICBvYmplY3QncyB1aWQgcHJvcGVydHkgY2FuIGJlIGluaGVyaXRlZCBmcm9tIHBhcmVudHMgb3Igbm90LlxuICogQHRocm93cyB7RXJyb3J9IHdoZW4gaW52b2tlZCB0byBpbmRpY2F0ZSB0aGUgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuLlxuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VWlkKG9iamVjdCwgbm9Jbmhlcml0YW5jZSkge1xuXHRpZiAob2JqZWN0KSB7XG5cdFx0bGV0IGlkID0gb2JqZWN0W1VJRF9QUk9QRVJUWV07XG5cdFx0aWYgKG5vSW5oZXJpdGFuY2UgJiYgIW9iamVjdC5oYXNPd25Qcm9wZXJ0eShVSURfUFJPUEVSVFkpKSB7XG5cdFx0XHRpZCA9IG51bGw7XG5cdFx0fVxuXHRcdHJldHVybiBpZCB8fCAob2JqZWN0W1VJRF9QUk9QRVJUWV0gPSB1bmlxdWVJZENvdW50ZXJfKyspO1xuXHR9XG5cdHJldHVybiB1bmlxdWVJZENvdW50ZXJfKys7XG59XG5cbi8qKlxuICogVGhlIGlkZW50aXR5IGZ1bmN0aW9uLiBSZXR1cm5zIGl0cyBmaXJzdCBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kj19IHJldHVyblZhbHVlIFRoZSBzaW5nbGUgdmFsdWUgdGhhdCB3aWxsIGJlIHJldHVybmVkLlxuICogQHJldHVybiB7P30gVGhlIGZpcnN0IGFyZ3VtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHlGdW5jdGlvbihyZXR1cm5WYWx1ZSkge1xuXHRyZXR1cm4gcmV0dXJuVmFsdWU7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBib29sZWFuLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYm9vbGVhbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbih2YWwpIHtcblx0cmV0dXJuIHR5cGVvZiB2YWwgPT09ICdib29sZWFuJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBub3QgdW5kZWZpbmVkLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmKHZhbCkge1xuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIG5vdCB1bmRlZmluZWQgb3IgbnVsbC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEZWZBbmROb3ROdWxsKHZhbCkge1xuXHRyZXR1cm4gaXNEZWYodmFsKSAmJiAhaXNOdWxsKHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgZG9jdW1lbnQuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRG9jdW1lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSA5O1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIGRvY3VtZW50LWZyYWdtZW50LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RvY3VtZW50RnJhZ21lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSAxMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBkb20gZWxlbWVudC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbGVtZW50KHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC5ub2RlVHlwZSA9PT0gMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIGZ1bmN0aW9uLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsKSB7XG5cdHJldHVybiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBudWxsLlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bGwodmFsKSB7XG5cdHJldHVybiB2YWwgPT09IG51bGw7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBhIG51bWJlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtYmVyKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ251bWJlcic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgd2luZG93LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1dpbmRvdyh2YWwpIHtcblx0cmV0dXJuIHZhbCAhPT0gbnVsbCAmJiB2YWwgPT09IHZhbC53aW5kb3c7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gb2JqZWN0LiBUaGlzIGluY2x1ZGVzIGFycmF5c1xuICogYW5kIGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGFuIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbCkge1xuXHRjb25zdCB0eXBlID0gdHlwZW9mIHZhbDtcblx0cmV0dXJuICh0eXBlID09PSAnb2JqZWN0JyAmJiB2YWwgIT09IG51bGwpIHx8IHR5cGUgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgUHJvbWlzZS5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQcm9taXNlKHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWwudGhlbiA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgfHwgdmFsIGluc3RhbmNlb2YgU3RyaW5nO1xufVxuXG4vKipcbiAqIFNldHMgdG8gdHJ1ZSBpZiBydW5uaW5nIGluc2lkZSBOb2RlLmpzIGVudmlyb25tZW50IHdpdGggZXh0cmEgY2hlY2sgZm9yXG4gKiBgcHJvY2Vzcy5icm93c2VyYCB0byBza2lwIEthcm1hIHJ1bm5lciBlbnZpcm9ubWVudC4gS2FybWEgZW52aXJvbm1lbnQgaGFzXG4gKiBgcHJvY2Vzc2AgZGVmaW5lZCBldmVuIHRob3VnaCBpdCBydW5zIG9uIHRoZSBicm93c2VyLlxuICogQHBhcmFtIHs/T2JqZWN0fSBvcHRpb25zIENvbnRhaW5zIGBjaGVja0VudmAgcHJvcGVydHkgd2hpY2ggaWYgdHJ1ZSwgY2hlY2tzXG4gKiB0aGUgTk9ERV9FTlYgdmFyaWFibGUuIElmIE5PREVfRU5WIGVxdWFscyAndGVzdCcsIHRoZSBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2VydmVyU2lkZShvcHRpb25zID0ge2NoZWNrRW52OiB0cnVlfSkge1xuXHRsZXQgc2VydmVyU2lkZSA9IHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiAhcHJvY2Vzcy5icm93c2VyO1xuXHRpZiAoc2VydmVyU2lkZSAmJiBvcHRpb25zLmNoZWNrRW52KSB7XG5cdFx0c2VydmVyU2lkZSA9XG5cdFx0XHR0eXBlb2YgcHJvY2Vzcy5lbnYgIT09ICd1bmRlZmluZWQnICYmXG5cdFx0XHRwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnO1xuXHR9XG5cdHJldHVybiBzZXJ2ZXJTaWRlO1xufVxuXG4vKipcbiAqIE51bGwgZnVuY3Rpb24gdXNlZCBmb3IgZGVmYXVsdCB2YWx1ZXMgb2YgY2FsbGJhY2tzLCBldGMuXG4gKiBAcmV0dXJuIHt2b2lkfSBOb3RoaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVsbEZ1bmN0aW9uKCkge31cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gVGhpcyBmaWxlIGV4aXN0cyBqdXN0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgbWFraW5nIHN1cmUgdGhhdCBvbGRcbi8vIGRlZmF1bHQgaW1wb3J0cyBmb3IgdGhpcyBmaWxlIHN0aWxsIHdvcmsuIEl0J3MgYmVzdCB0byB1c2UgdGhlIG5hbWVkIGV4cG9ydHNcbi8vIGZvciBlYWNoIGZ1bmN0aW9uIGluc3RlYWQgdGhvdWdoLCBzaW5jZSB0aGF0IGFsbG93cyBidW5kbGVycyBsaWtlIFJvbGx1cCB0b1xuLy8gcmVkdWNlIHRoZSBidW5kbGUgc2l6ZSBieSByZW1vdmluZyB1bnVzZWQgY29kZS5cbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnLi9jb3JlTmFtZWQnO1xuXG5leHBvcnQgZGVmYXVsdCBjb3JlO1xuZXhwb3J0IHtjb3JlfTtcbmV4cG9ydCAqIGZyb20gJy4vY29yZU5hbWVkJztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBhcnJheSBvcGVyYXRpb25zXG4gKi9cbmNsYXNzIGFycmF5IHtcblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJyYXlzIGhhdmUgdGhlIHNhbWUgY29udGVudC5cblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjFcblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBlcXVhbChhcnIxLCBhcnIyKSB7XG5cdFx0aWYgKGFycjEgPT09IGFycjIpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRpZiAoYXJyMS5sZW5ndGggIT09IGFycjIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycjFbaV0gIT09IGFycjJbaV0pIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZ2l2ZW4gYXJyYXkgdGhhdCBpc24ndCB1bmRlZmluZWQuXG5cdCAqIEBwYXJhbSB7IUFycmF5fSBhcnJcblx0ICogQHJldHVybiB7Kn1cblx0ICovXG5cdHN0YXRpYyBmaXJzdERlZmluZWRWYWx1ZShhcnIpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycltpXSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBhcnJbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRyYW5zZm9ybXMgdGhlIGlucHV0IG5lc3RlZCBhcnJheSB0byBiZWNvbWUgZmxhdC5cblx0ICogQHBhcmFtIHtBcnJheS48KnxBcnJheS48Kj4+fSBhcnIgTmVzdGVkIGFycmF5IHRvIGZsYXR0ZW4uXG5cdCAqIEBwYXJhbSB7QXJyYXkuPCo+PX0gb3V0cHV0IE9wdGlvbmFsIG91dHB1dCBhcnJheS5cblx0ICogQHJldHVybiB7QXJyYXkuPCo+fSBGbGF0IGFycmF5LlxuXHQgKi9cblx0c3RhdGljIGZsYXR0ZW4oYXJyLCBvdXRwdXQgPSBbXSkge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoQXJyYXkuaXNBcnJheShhcnJbaV0pKSB7XG5cdFx0XHRcdGFycmF5LmZsYXR0ZW4oYXJyW2ldLCBvdXRwdXQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3V0cHV0LnB1c2goYXJyW2ldKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGEgcGFydGljdWxhciB2YWx1ZSBmcm9tIGFuIGFycmF5LlxuXHQgKiBAcGFyYW0ge0FycmF5LjxUPn0gYXJyIEFycmF5IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge1R9IG9iaiBPYmplY3QgdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqIEB0ZW1wbGF0ZSBUXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlKGFyciwgb2JqKSB7XG5cdFx0Y29uc3QgaSA9IGFyci5pbmRleE9mKG9iaik7XG5cdFx0bGV0IHJ2O1xuXHRcdGlmICgocnYgPSBpID49IDApKSB7XG5cdFx0XHRhcnJheS5yZW1vdmVBdChhcnIsIGkpO1xuXHRcdH1cblx0XHRyZXR1cm4gcnY7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBmcm9tIGFuIGFycmF5IHRoZSBlbGVtZW50IGF0IGluZGV4IGlcblx0ICogQHBhcmFtIHtBcnJheX0gYXJyIEFycmF5IG9yIGFycmF5IGxpa2Ugb2JqZWN0IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gaSBUaGUgaW5kZXggdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlQXQoYXJyLCBpKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zcGxpY2UuY2FsbChhcnIsIGksIDEpLmxlbmd0aCA9PT0gMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTbGljZXMgdGhlIGdpdmVuIGFycmF5LCBqdXN0IGxpa2UgQXJyYXkucHJvdG90eXBlLnNsaWNlLCBidXQgdGhpc1xuXHQgKiBpcyBmYXN0ZXIgYW5kIHdvcmtpbmcgb24gYWxsIGFycmF5LWxpa2Ugb2JqZWN0cyAobGlrZSBhcmd1bWVudHMpLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGFyciBBcnJheS1saWtlIG9iamVjdCB0byBzbGljZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBpbmRleCB0aGF0IHNob3VsZCBzdGFydCB0aGUgc2xpY2UuXG5cdCAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIFRoZSBpbmRleCB3aGVyZSB0aGUgc2xpY2Ugc2hvdWxkIGVuZCwgbm90XG5cdCAqICAgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIGFycmF5LiBJZiBub3QgZ2l2ZW4sIGFsbCBlbGVtZW50cyBhZnRlciB0aGVcblx0ICogICBzdGFydCBpbmRleCB3aWxsIGJlIGluY2x1ZGVkLlxuXHQgKiBAcmV0dXJuIHshQXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc2xpY2UoYXJyLCBzdGFydCwgZW5kID0gYXJyLmxlbmd0aCkge1xuXHRcdGNvbnN0IHNsaWNlZCA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG5cdFx0XHRzbGljZWQucHVzaChhcnJbaV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gc2xpY2VkO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGFycmF5O1xuIiwiLyogIVxuICogUG9seWZpbGwgZnJvbSBHb29nbGUncyBDbG9zdXJlIExpYnJhcnkuXG4gKiBDb3B5cmlnaHQgMjAxMyBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2lzU2VydmVyU2lkZX0gZnJvbSAnLi4vY29yZU5hbWVkJztcblxuY29uc3QgYXN5bmMgPSB7fTtcblxuLyoqXG4gKiBUaHJvdyBhbiBpdGVtIHdpdGhvdXQgaW50ZXJydXB0aW5nIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LiAgRm9yXG4gKiBleGFtcGxlLCBpZiBwcm9jZXNzaW5nIGEgZ3JvdXAgb2YgaXRlbXMgaW4gYSBsb29wLCBzb21ldGltZXMgaXQgaXMgdXNlZnVsXG4gKiB0byByZXBvcnQgYW4gZXJyb3Igd2hpbGUgc3RpbGwgYWxsb3dpbmcgdGhlIHJlc3Qgb2YgdGhlIGJhdGNoIHRvIGJlXG4gKiBwcm9jZXNzZWQuXG4gKiBAcGFyYW0geyp9IGV4Y2VwdGlvblxuICovXG5hc3luYy50aHJvd0V4Y2VwdGlvbiA9IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuXHQvLyBFYWNoIHRocm93IG5lZWRzIHRvIGJlIGluIGl0cyBvd24gY29udGV4dC5cblx0YXN5bmMubmV4dFRpY2soZnVuY3Rpb24oKSB7XG5cdFx0dGhyb3cgZXhjZXB0aW9uO1xuXHR9KTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrIGp1c3QgYmVmb3JlIHRoZSBjdXJyZW50IGNhbGxzdGFjayB1bndpbmRzLCBvciBhc1xuICogc29vbiBhcyBwb3NzaWJsZSBhZnRlciB0aGUgY3VycmVudCBKUyBleGVjdXRpb24gY29udGV4dC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpUSElTKX0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7VEhJUz19IGNvbnRleHQgT2JqZWN0IHRvIHVzZSBhcyB0aGUgXCJ0aGlzIHZhbHVlXCIgd2hlbiBjYWxsaW5nXG4gKiAgICAgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uLlxuICogQHRlbXBsYXRlIFRISVNcbiAqL1xuYXN5bmMucnVuID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0aWYgKCFhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXykge1xuXHRcdC8vIE5vdGhpbmcgaXMgY3VycmVudGx5IHNjaGVkdWxlZCwgc2NoZWR1bGUgaXQgbm93LlxuXHRcdGFzeW5jLm5leHRUaWNrKGFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlKTtcblx0XHRhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IHRydWU7XG5cdH1cblxuXHRhc3luYy5ydW4ud29ya1F1ZXVlXy5wdXNoKG5ldyBhc3luYy5ydW4uV29ya0l0ZW1fKGNhbGxiYWNrLCBjb250ZXh0KSk7XG59O1xuXG4vKiogQHByaXZhdGUge2Jvb2xlYW59ICovXG5hc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IGZhbHNlO1xuXG4vKiogQHByaXZhdGUgeyFBcnJheS48IWFzeW5jLnJ1bi5Xb3JrSXRlbV8+fSAqL1xuYXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblxuLyoqXG4gKiBSdW4gYW55IHBlbmRpbmcgYXN5bmMucnVuIHdvcmsgaXRlbXMuIFRoaXMgZnVuY3Rpb24gaXMgbm90IGludGVuZGVkXG4gKiBmb3IgZ2VuZXJhbCB1c2UsIGJ1dCBmb3IgdXNlIGJ5IGVudHJ5IHBvaW50IGhhbmRsZXJzIHRvIHJ1biBpdGVtcyBhaGVhZCBvZlxuICogYXN5bmMubmV4dFRpY2suXG4gKi9cbmFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlID0gZnVuY3Rpb24oKSB7XG5cdC8vIE5PVEU6IGFkZGl0aW9uYWwgd29yayBxdWV1ZSBpdGVtcyBtYXkgYmUgcHVzaGVkIHdoaWxlIHByb2Nlc3NpbmcuXG5cdHdoaWxlIChhc3luYy5ydW4ud29ya1F1ZXVlXy5sZW5ndGgpIHtcblx0XHQvLyBEb24ndCBsZXQgdGhlIHdvcmsgcXVldWUgZ3JvdyBpbmRlZmluaXRlbHkuXG5cdFx0Y29uc3Qgd29ya0l0ZW1zID0gYXN5bmMucnVuLndvcmtRdWV1ZV87XG5cdFx0YXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHdvcmtJdGVtcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgd29ya0l0ZW0gPSB3b3JrSXRlbXNbaV07XG5cdFx0XHR0cnkge1xuXHRcdFx0XHR3b3JrSXRlbS5mbi5jYWxsKHdvcmtJdGVtLnNjb3BlKTtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0YXN5bmMudGhyb3dFeGNlcHRpb24oZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gVGhlcmUgYXJlIG5vIG1vcmUgd29yayBpdGVtcywgcmVzZXQgdGhlIHdvcmsgcXVldWUuXG5cdGFzeW5jLnJ1bi53b3JrUXVldWVTY2hlZHVsZWRfID0gZmFsc2U7XG59O1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICogQGZpbmFsXG4gKiBAc3RydWN0XG4gKiBAcHJpdmF0ZVxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gZm5cbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx8dW5kZWZpbmVkfSBzY29wZVxuICovXG5hc3luYy5ydW4uV29ya0l0ZW1fID0gZnVuY3Rpb24oZm4sIHNjb3BlKSB7XG5cdC8qKiBAY29uc3QgKi9cblx0dGhpcy5mbiA9IGZuO1xuXHQvKiogQGNvbnN0ICovXG5cdHRoaXMuc2NvcGUgPSBzY29wZTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrcyBhcyBzb29uIGFzIHBvc3NpYmxlIGFmdGVyIHRoZSBjdXJyZW50IEpTXG4gKiBleGVjdXRpb24gY29udGV4dC4gc2V0VGltZW91dCjigKYsIDApIGFsd2F5cyB0YWtlcyBhdCBsZWFzdCA1bXMgZm9yIGxlZ2FjeVxuICogcmVhc29ucy5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpTQ09QRSl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhc1xuICogICAgIHBvc3NpYmxlLlxuICogQHBhcmFtIHtTQ09QRT19IGNvbnRleHQgT2JqZWN0IGluIHdob3NlIHNjb3BlIHRvIGNhbGwgdGhlIGxpc3RlbmVyLlxuICogQHRlbXBsYXRlIFNDT1BFXG4gKi9cbmFzeW5jLm5leHRUaWNrID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0bGV0IGNiID0gY2FsbGJhY2s7XG5cdGlmIChjb250ZXh0KSB7XG5cdFx0Y2IgPSBjYWxsYmFjay5iaW5kKGNvbnRleHQpO1xuXHR9XG5cdGNiID0gYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyhjYik7XG5cdC8vIExvb2sgZm9yIGFuZCBjYWNoZSB0aGUgY3VzdG9tIGZhbGxiYWNrIHZlcnNpb24gb2Ygc2V0SW1tZWRpYXRlLlxuXHRpZiAoIWFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8pIHtcblx0XHRpZiAoXG5cdFx0XHR0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHRpc1NlcnZlclNpZGUoe2NoZWNrRW52OiBmYWxzZX0pXG5cdFx0KSB7XG5cdFx0XHRhc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfID0gc2V0SW1tZWRpYXRlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRcdGFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8gPSBhc3luYy5uZXh0VGljay5nZXRTZXRJbW1lZGlhdGVFbXVsYXRvcl8oKTtcblx0XHR9XG5cdH1cblx0YXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyhjYik7XG59O1xuXG4vKipcbiAqIENhY2hlIGZvciB0aGUgc2V0SW1tZWRpYXRlIGltcGxlbWVudGF0aW9uLlxuICogQHR5cGUge2Z1bmN0aW9uKGZ1bmN0aW9uKCkpfVxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyA9IG51bGw7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB0aGUgYmVzdCBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbiB0byBydW4gYSBmdW5jdGlvbiBhcyBzb29uIGFzXG4gKiB0aGUgSlMgZXZlbnQgbG9vcCBpcyBpZGxlLlxuICogQHJldHVybiB7ZnVuY3Rpb24oZnVuY3Rpb24oKSl9IFRoZSBcInNldEltbWVkaWF0ZVwiIGltcGxlbWVudGF0aW9uLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfID0gZnVuY3Rpb24oKSB7XG5cdC8vIENyZWF0ZSBhIHByaXZhdGUgbWVzc2FnZSBjaGFubmVsIGFuZCB1c2UgaXQgdG8gcG9zdE1lc3NhZ2UgZW1wdHkgbWVzc2FnZXNcblx0Ly8gdG8gb3Vyc2VsdmVzLlxuXHRsZXQgQ2hhbm5lbDtcblxuXHQvLyBWZXJpZnkgaWYgdmFyaWFibGUgaXMgZGVmaW5lZCBvbiB0aGUgY3VycmVudCBydW50aW1lIChpLmUuLCBub2RlLCBicm93c2VyKS5cblx0Ly8gQ2FuJ3QgdXNlIHR5cGVvZiBlbmNsb3NlZCBpbiBhIGZ1bmN0aW9uIChzdWNoIGFzIGNvcmUuaXNGdW5jdGlvbikgb3IgYW5cblx0Ly8gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBhbiBlbnZpcm9ubWVudFxuXHQvLyB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdW5kZWZpbmVkLlxuXHRpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0Q2hhbm5lbCA9IE1lc3NhZ2VDaGFubmVsO1xuXHR9XG5cblx0Ly8gSWYgTWVzc2FnZUNoYW5uZWwgaXMgbm90IGF2YWlsYWJsZSBhbmQgd2UgYXJlIGluIGEgYnJvd3NlciwgaW1wbGVtZW50XG5cdC8vIGFuIGlmcmFtZSBiYXNlZCBwb2x5ZmlsbCBpbiBicm93c2VycyB0aGF0IGhhdmUgcG9zdE1lc3NhZ2UgYW5kXG5cdC8vIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIuIFRoZSBsYXR0ZXIgZXhjbHVkZXMgSUU4IGJlY2F1c2UgaXQgaGFzIGFcblx0Ly8gc3luY2hyb25vdXMgcG9zdE1lc3NhZ2UgaW1wbGVtZW50YXRpb24uXG5cdGlmIChcblx0XHR0eXBlb2YgQ2hhbm5lbCA9PT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuXHRcdHdpbmRvdy5wb3N0TWVzc2FnZSAmJlxuXHRcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG5cdCkge1xuXHRcdC8qKiBAY29uc3RydWN0b3IgKi9cblx0XHRDaGFubmVsID0gZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBNYWtlIGFuIGVtcHR5LCBpbnZpc2libGUgaWZyYW1lLlxuXHRcdFx0Y29uc3QgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG5cdFx0XHRpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdGlmcmFtZS5zcmMgPSAnJztcblx0XHRcdGlmcmFtZS50aXRsZSA9ICcnO1xuXHRcdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKGlmcmFtZSk7XG5cdFx0XHRjb25zdCB3aW4gPSBpZnJhbWUuY29udGVudFdpbmRvdztcblx0XHRcdGNvbnN0IGRvYyA9IHdpbi5kb2N1bWVudDtcblx0XHRcdGRvYy5vcGVuKCk7XG5cdFx0XHRkb2Mud3JpdGUoJycpO1xuXHRcdFx0ZG9jLmNsb3NlKCk7XG5cdFx0XHRjb25zdCBtZXNzYWdlID0gJ2NhbGxJbW1lZGlhdGUnICsgTWF0aC5yYW5kb20oKTtcblx0XHRcdGNvbnN0IG9yaWdpbiA9IHdpbi5sb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyB3aW4ubG9jYXRpb24uaG9zdDtcblx0XHRcdGNvbnN0IG9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0Ly8gVmFsaWRhdGUgb3JpZ2luIGFuZCBtZXNzYWdlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSB3YXNcblx0XHRcdFx0Ly8gaW50ZW5kZWQgZm9yIHVzLlxuXHRcdFx0XHRpZiAoZS5vcmlnaW4gIT09IG9yaWdpbiAmJiBlLmRhdGEgIT09IG1lc3NhZ2UpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5wb3J0MS5vbm1lc3NhZ2UoKTtcblx0XHRcdH0uYmluZCh0aGlzKTtcblx0XHRcdHdpbi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25tZXNzYWdlLCBmYWxzZSk7XG5cdFx0XHR0aGlzLnBvcnQxID0ge307XG5cdFx0XHR0aGlzLnBvcnQyID0ge1xuXHRcdFx0XHRwb3N0TWVzc2FnZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0d2luLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIG9yaWdpbik7XG5cdFx0XHRcdH0sXG5cdFx0XHR9O1xuXHRcdH07XG5cdH1cblx0aWYgKHR5cGVvZiBDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuXHRcdGNvbnN0IGNoYW5uZWwgPSBuZXcgQ2hhbm5lbCgpO1xuXHRcdC8vIFVzZSBhIGZpZm8gbGlua2VkIGxpc3QgdG8gY2FsbCBjYWxsYmFja3MgaW4gdGhlIHJpZ2h0IG9yZGVyLlxuXHRcdGxldCBoZWFkID0ge307XG5cdFx0bGV0IHRhaWwgPSBoZWFkO1xuXHRcdGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRoZWFkID0gaGVhZC5uZXh0O1xuXHRcdFx0Y29uc3QgY2IgPSBoZWFkLmNiO1xuXHRcdFx0aGVhZC5jYiA9IG51bGw7XG5cdFx0XHRjYigpO1xuXHRcdH07XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0XHR0YWlsLm5leHQgPSB7XG5cdFx0XHRcdGNiOiBjYixcblx0XHRcdH07XG5cdFx0XHR0YWlsID0gdGFpbC5uZXh0O1xuXHRcdFx0Y2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcblx0XHR9O1xuXHR9XG5cdC8vIEltcGxlbWVudGF0aW9uIGZvciBJRTYtODogU2NyaXB0IGVsZW1lbnRzIGZpcmUgYW4gYXN5bmNocm9ub3VzXG5cdC8vIG9ucmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aGVuIGluc2VydGVkIGludG8gdGhlIERPTS5cblx0aWYgKFxuXHRcdHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHQnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKVxuXHQpIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oY2IpIHtcblx0XHRcdGxldCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRcdHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0Ly8gQ2xlYW4gdXAgYW5kIGNhbGwgdGhlIGNhbGxiYWNrLlxuXHRcdFx0XHRzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcblx0XHRcdFx0c2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcblx0XHRcdFx0c2NyaXB0ID0gbnVsbDtcblx0XHRcdFx0Y2IoKTtcblx0XHRcdFx0Y2IgPSBudWxsO1xuXHRcdFx0fTtcblx0XHRcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH07XG5cdH1cblx0Ly8gRmFsbCBiYWNrIHRvIHNldFRpbWVvdXQgd2l0aCAwLiBJbiBicm93c2VycyB0aGlzIGNyZWF0ZXMgYSBkZWxheSBvZiA1bXNcblx0Ly8gb3IgbW9yZS5cblx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0c2V0VGltZW91dChjYiwgMCk7XG5cdH07XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGlzIG92ZXJyaWRlZCB0byBwcm90ZWN0IGNhbGxiYWNrcyB3aXRoIGVudHJ5IHBvaW50XG4gKiBtb25pdG9yIGlmIHRoZSBhcHBsaWNhdGlvbiBtb25pdG9ycyBlbnRyeSBwb2ludHMuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhcyBwb3NzaWJsZS5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKCl9IFRoZSB3cmFwcGVkIGNhbGxiYWNrLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG5cdHJldHVybiBjYWxsYmFjaztcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIERpc3Bvc2FibGUgdXRpbGl0eS4gV2hlbiBpbmhlcml0ZWQgcHJvdmlkZXMgdGhlIGBkaXNwb3NlYCBmdW5jdGlvbiB0byBpdHNcbiAqIHN1YmNsYXNzLCB3aGljaCBpcyByZXNwb25zaWJsZSBmb3IgZGlzcG9zaW5nIG9mIGFueSBvYmplY3QgcmVmZXJlbmNlc1xuICogd2hlbiBhbiBpbnN0YW5jZSB3b24ndCBiZSB1c2VkIGFueW1vcmUuIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlXG4gKiBgZGlzcG9zZUludGVybmFsYCB0byBpbXBsZW1lbnQgYW55IHNwZWNpZmljIGRpc3Bvc2luZyBsb2dpYy5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5jbGFzcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIERpc3Bvc2FibGUgY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdC8qKlxuXHRcdCAqIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGluc3RhbmNlIGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZGlzcG9zZWRfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLiBDYWxscyBgZGlzcG9zZUludGVybmFsYC5cblx0ICovXG5cdGRpc3Bvc2UoKSB7XG5cdFx0aWYgKCF0aGlzLmRpc3Bvc2VkXykge1xuXHRcdFx0dGhpcy5kaXNwb3NlSW50ZXJuYWwoKTtcblx0XHRcdHRoaXMuZGlzcG9zZWRfID0gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gaW1wbGVtZW50IGFueSBzcGVjaWZpY1xuXHQgKiBkaXNwb3NpbmcgbG9naWMgKGxpa2UgY2xlYXJpbmcgcmVmZXJlbmNlcyBhbmQgY2FsbGluZyBgZGlzcG9zZWAgb24gb3RoZXJcblx0ICogZGlzcG9zYWJsZXMpLlxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge31cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoaXMgaW5zdGFuY2UgaGFzIGFscmVhZHkgYmVlbiBkaXNwb3NlZC5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzRGlzcG9zZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZGlzcG9zZWRfO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERpc3Bvc2FibGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3Igb2JqZWN0IG9wZXJhdGlvbnNcbiAqL1xuY2xhc3Mgb2JqZWN0IHtcblx0LyoqXG5cdCAqIENvcGllcyBhbGwgdGhlIG1lbWJlcnMgb2YgYSBzb3VyY2Ugb2JqZWN0IHRvIGEgdGFyZ2V0IG9iamVjdC5cblx0ICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUYXJnZXQgb2JqZWN0LlxuXHQgKiBAcGFyYW0gey4uLk9iamVjdH0gdmFyX2FyZ3MgVGhlIG9iamVjdHMgZnJvbSB3aGljaCB2YWx1ZXMgd2lsbCBiZSBjb3BpZWQuXG5cdCAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyB0aGUgdGFyZ2V0IG9iamVjdCByZWZlcmVuY2UuXG5cdCAqL1xuXHRzdGF0aWMgbWl4aW4odGFyZ2V0LCAuLi5hcmdzKSB7XG5cdFx0bGV0IGtleTtcblx0XHRsZXQgc291cmNlO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0c291cmNlID0gYXJnc1tpXTtcblx0XHRcdC8vIFBvc3NpYmxlIHByb3RvdHlwZSBjaGFpbiBsZWFrLCBicmVha3MgMSBtZXRhbC1kb20gYW5kXG5cdFx0XHQvLyAxIG1ldGFsLWluY3JlbWVudGFsLWRvbSB0ZXN0IGlmIGd1YXJkLWZvci1pbiBydWxlIGlzIGFkZHJlc3NlZFxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cdFx0XHRmb3IgKGtleSBpbiBzb3VyY2UpIHtcblx0XHRcdFx0dGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRhcmdldDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGFuIG9iamVjdCBiYXNlZCBvbiBpdHMgZnVsbHkgcXVhbGlmaWVkIGV4dGVybmFsIG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZS5cblx0ICogQHBhcmFtIHtvYmplY3Q9fSBzY29wZSBUaGUgb2JqZWN0IHdpdGhpbiB3aGljaCB0byBsb29rOyBkZWZhdWx0IGlzXG5cdCAqICAgICA8Y29kZT53aW5kb3c8L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHs/fSBUaGUgdmFsdWUgKG9iamVjdCBvciBwcmltaXRpdmUpIG9yLCBpZiBub3QgZm91bmQsIHVuZGVmaW5lZC5cblx0ICovXG5cdHN0YXRpYyBnZXRPYmplY3RCeU5hbWUobmFtZSwgc2NvcGUgPSB3aW5kb3cpIHtcblx0XHRjb25zdCBwYXJ0cyA9IG5hbWUuc3BsaXQoJy4nKTtcblx0XHRyZXR1cm4gcGFydHMucmVkdWNlKChwYXJ0LCBrZXkpID0+IHBhcnRba2V5XSwgc2NvcGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUga2V5cyBhcyB0aGUgZ2l2ZW4gb25lLCBidXQgd2l0aFxuXHQgKiB0aGVpciB2YWx1ZXMgc2V0IHRvIHRoZSByZXR1cm4gdmFsdWVzIG9mIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24uXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gb2JqXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKHN0cmluZywgKil9IGZuXG5cdCAqIEByZXR1cm4geyFPYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgbWFwKG9iaiwgZm4pIHtcblx0XHRjb25zdCBtYXBwZWRPYmogPSB7fTtcblx0XHRjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG1hcHBlZE9ialtrZXlzW2ldXSA9IGZuKGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXBwZWRPYmo7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSB0d28gZ2l2ZW4gb2JqZWN0cyBhcmUgZXF1YWwuIFRoaXMgaXMgZG9uZSB2aWEgYSBzaGFsbG93XG5cdCAqIGNoZWNrLCBpbmNsdWRpbmcgb25seSB0aGUga2V5cyBkaXJlY3RseSBjb250YWluZWQgYnkgdGhlIDIgb2JqZWN0cy5cblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajFcblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBzaGFsbG93RXF1YWwob2JqMSwgb2JqMikge1xuXHRcdGlmIChvYmoxID09PSBvYmoyKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBrZXlzMSA9IE9iamVjdC5rZXlzKG9iajEpO1xuXHRcdGNvbnN0IGtleXMyID0gT2JqZWN0LmtleXMob2JqMik7XG5cdFx0aWYgKGtleXMxLmxlbmd0aCAhPT0ga2V5czIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKG9iajFba2V5czFbaV1dICE9PSBvYmoyW2tleXMxW2ldXSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9iamVjdDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBzdHJpbmcgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBzdHJpbmcge1xuXHQvKipcblx0ICogQ29tcGFyZXMgdGhlIGdpdmVuIHN0cmluZ3Mgd2l0aG91dCB0YWtpbmcgdGhlIGNhc2UgaW50byBhY2NvdW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHN0cjFcblx0ICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdHIyXG5cdCAqIEByZXR1cm4ge251bWJlcn0gRWl0aGVyIC0xLCAwIG9yIDEsIGFjY29yZGluZyB0byBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzXG5cdCAqICAgICBcInNtYWxsZXJcIiwgZXF1YWwgb3IgXCJiaWdnZXJcIiB0aGFuIHRoZSBzZWNvbmQgZ2l2ZW4gc3RyaW5nLlxuXHQgKi9cblx0c3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbXBhcmUoc3RyMSwgc3RyMikge1xuXHRcdGNvbnN0IHRlc3QxID0gU3RyaW5nKHN0cjEpLnRvTG93ZXJDYXNlKCk7XG5cdFx0Y29uc3QgdGVzdDIgPSBTdHJpbmcoc3RyMikudG9Mb3dlckNhc2UoKTtcblxuXHRcdGlmICh0ZXN0MSA8IHRlc3QyKSB7XG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0fSBlbHNlIGlmICh0ZXN0MSA9PT0gdGVzdDIpIHtcblx0XHRcdHJldHVybiAwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgYnJlYWtpbmcgc3BhY2VzIGZyb20gdGhlIGxlZnQgYW5kIHJpZ2h0IG9mIHRoZSBzdHJpbmcgYW5kXG5cdCAqIGNvbGxhcHNlcyB0aGUgc2VxdWVuY2VzIG9mIGJyZWFraW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlIGludG8gc2luZ2xlIHNwYWNlcy5cblx0ICogVGhlIG9yaWdpbmFsIGFuZCB0aGUgcmVzdWx0IHN0cmluZ3MgcmVuZGVyIHRoZSBzYW1lIHdheSBpbiBIVE1MLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIEEgc3RyaW5nIGluIHdoaWNoIHRvIGNvbGxhcHNlIHNwYWNlcy5cblx0ICogQHJldHVybiB7c3RyaW5nfSBDb3B5IG9mIHRoZSBzdHJpbmcgd2l0aCBub3JtYWxpemVkIGJyZWFraW5nIHNwYWNlcy5cblx0ICovXG5cdHN0YXRpYyBjb2xsYXBzZUJyZWFraW5nU3BhY2VzKHN0cikge1xuXHRcdHJldHVybiBzdHJcblx0XHRcdC5yZXBsYWNlKC9bXFx0XFxyXFxuIF0rL2csICcgJylcblx0XHRcdC5yZXBsYWNlKC9eW1xcdFxcclxcbiBdK3xbXFx0XFxyXFxuIF0rJC9nLCAnJyk7XG5cdH1cblxuXHQvKipcblx0ICogRXNjYXBlcyBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcgdGhhdCBhcmUgbm90IHNhZmUgdG8gdXNlIGluIGEgUmVnRXhwLlxuXHQgKiBAcGFyYW0geyp9IHN0ciBUaGUgc3RyaW5nIHRvIGVzY2FwZS4gSWYgbm90IGEgc3RyaW5nLCBpdCB3aWxsIGJlIGNhc3RlZFxuXHQgKiAgICAgdG8gb25lLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEEgUmVnRXhwIHNhZmUsIGVzY2FwZWQgY29weSBvZiB7QGNvZGUgc30uXG5cdCAqL1xuXHRzdGF0aWMgZXNjYXBlUmVnZXgoc3RyKSB7XG5cdFx0cmV0dXJuIFN0cmluZyhzdHIpXG5cdFx0XHQucmVwbGFjZSgvKFstKClbXFxde30rPyouJF58LDojPCFcXFxcXSkvZywgJ1xcXFwkMScpXG5cdFx0XHQucmVwbGFjZSgvXFx4MDgvZywgJ1xcXFx4MDgnKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhdCBsZWFzdCA2NC1iaXRzIG9mIHJhbmRvbW5lc3MuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQSByYW5kb20gc3RyaW5nLCBlLmcuIHNuMXM3dmI0Z2NpYy5cblx0ICovXG5cdHN0YXRpYyBnZXRSYW5kb21TdHJpbmcoKSB7XG5cdFx0Y29uc3QgeCA9IDIxNDc0ODM2NDg7XG5cdFx0cmV0dXJuIChcblx0XHRcdE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHgpLnRvU3RyaW5nKDM2KSArXG5cdFx0XHRNYXRoLmFicyhNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB4KSBeIERhdGUubm93KCkpLnRvU3RyaW5nKDM2KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FsY3VsYXRlcyB0aGUgaGFzaGNvZGUgZm9yIGEgc3RyaW5nLiBUaGUgaGFzaGNvZGUgdmFsdWUgaXMgY29tcHV0ZWQgYnlcblx0ICogdGhlIHN1bSBhbGdvcml0aG06IHNbMF0qMzFeKG4tMSkgKyBzWzFdKjMxXihuLTIpICsgLi4uICsgc1tuLTFdLiBBIG5pY2Vcblx0ICogcHJvcGVydHkgb2YgdXNpbmcgMzEgcHJpbWUgaXMgdGhhdCB0aGUgbXVsdGlwbGljYXRpb24gY2FuIGJlIHJlcGxhY2VkIGJ5XG5cdCAqIGEgc2hpZnQgYW5kIGEgc3VidHJhY3Rpb24gZm9yIGJldHRlciBwZXJmb3JtYW5jZTogMzEqaSA9PSAoaTw8NSktaS5cblx0ICogTW9kZXJuIFZNcyBkbyB0aGlzIHNvcnQgb2Ygb3B0aW1pemF0aW9uIGF1dG9tYXRpY2FsbHkuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB2YWwgVGFyZ2V0IHN0cmluZy5cblx0ICogQHJldHVybiB7TnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgaGFzaGNvZGUuXG5cdCAqL1xuXHRzdGF0aWMgaGFzaENvZGUodmFsKSB7XG5cdFx0bGV0IGhhc2ggPSAwO1xuXHRcdGZvciAobGV0IGkgPSAwLCBsZW4gPSB2YWwubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGhhc2ggPSAzMSAqIGhhc2ggKyB2YWwuY2hhckNvZGVBdChpKTtcblx0XHRcdGhhc2ggJT0gMHgxMDAwMDAwMDA7XG5cdFx0fVxuXHRcdHJldHVybiBoYXNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlcGxhY2VzIGludGVydmFsIGludG8gdGhlIHN0cmluZyB3aXRoIHNwZWNpZmllZCB2YWx1ZSwgZS5nLlxuXHQgKiBgcmVwbGFjZUludGVydmFsKFwiYWJjZGVcIiwgMSwgNCwgXCJcIilgIHJldHVybnMgXCJhZVwiLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBpbnB1dCBzdHJpbmcuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydCBTdGFydCBpbnRlcnZhbCBwb3NpdGlvbiB0byBiZSByZXBsYWNlZC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IGVuZCBFbmQgaW50ZXJ2YWwgcG9zaXRpb24gdG8gYmUgcmVwbGFjZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdGhhdCByZXBsYWNlcyB0aGUgc3BlY2lmaWVkIGludGVydmFsLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgcmVwbGFjZUludGVydmFsKHN0ciwgc3RhcnQsIGVuZCwgdmFsdWUpIHtcblx0XHRyZXR1cm4gc3RyLnN1YnN0cmluZygwLCBzdGFydCkgKyB2YWx1ZSArIHN0ci5zdWJzdHJpbmcoZW5kKTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBzdHJpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuICogQHBhcmFtIHsqPX0gb3B0X3VyaSBPcHRpb25hbCBzdHJpbmcgVVJJIHRvIHBhcnNlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlRnJvbUFuY2hvcihvcHRfdXJpKSB7XG5cdHZhciBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXHRsaW5rLmhyZWYgPSBvcHRfdXJpO1xuXG5cdGlmKGxpbmsucHJvdG9jb2wgPT09ICc6JyB8fCAhLzovLnRlc3QobGluay5ocmVmKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7b3B0X3VyaX0gaXMgbm90IGEgdmFsaWQgVVJMYCk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdGhhc2g6IGxpbmsuaGFzaCxcblx0XHRob3N0bmFtZTogbGluay5ob3N0bmFtZSxcblx0XHRwYXNzd29yZDogbGluay5wYXNzd29yZCxcblx0XHRwYXRobmFtZTogbGluay5wYXRobmFtZVswXSA9PT0gJy8nID8gbGluay5wYXRobmFtZSA6ICcvJyArIGxpbmsucGF0aG5hbWUsXG5cdFx0cG9ydDogbGluay5wb3J0LFxuXHRcdHByb3RvY29sOiBsaW5rLnByb3RvY29sLFxuXHRcdHNlYXJjaDogbGluay5zZWFyY2gsXG5cdFx0dXNlcm5hbWU6IGxpbmsudXNlcm5hbWVcblx0fTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgcGFyc2VGcm9tQW5jaG9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHBhcnNlRnJvbUFuY2hvciBmcm9tICcuL3BhcnNlRnJvbUFuY2hvcic7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LiBUaGUgVVJMIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZFxuICogd2hlbiBwcmVzZW50LCBvdGhlcndpc2Ugd2UnbGwgZmFsbCBiYWNrIHRvIHRoZSBhbmNob3Igbm9kZSBlbGVtZW50LlxuICogQHBhcmFtIHsqPX0gb3B0X3VyaSBPcHRpb25hbCBzdHJpbmcgVVJJIHRvIHBhcnNlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlKG9wdF91cmkpIHtcblx0aWYgKGlzRnVuY3Rpb24oVVJMKSAmJiBVUkwubGVuZ3RoKSB7XG5cdFx0Y29uc3QgdXJsID0gbmV3IFVSTChvcHRfdXJpKTtcblxuXHRcdC8vIFNhZmFyaSBCcm93c2VycyB3aWxsIGNhcCBwb3J0IHRvIHRoZSBtYXggMTYtYml0IHVuc2lnbmVkIGludGVnZXIgKDY1NTM1KSBpbnN0ZWFkXG5cdFx0Ly8gb2YgdGhyb3dpbmcgYSBUeXBlRXJyb3IgYXMgcGVyIHNwZWMuIEl0IHdpbGwgc3RpbGwga2VlcCB0aGUgcG9ydCBudW1iZXIgaW4gdGhlXG5cdFx0Ly8gaHJlZiBhdHRyaWJ1dGUsIHNvIHdlIGNhbiB1c2UgdGhpcyBtaXNtYXRjaCB0byByYWlzZSB0aGUgZXhwZWN0ZWQgZXhjZXB0aW9uLlxuXHRcdGlmICh1cmwucG9ydCAmJiB1cmwuaHJlZi5pbmRleE9mKHVybC5wb3J0KSA9PT0gLTEpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7b3B0X3VyaX0gaXMgbm90IGEgdmFsaWQgVVJMYCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVybDtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gcGFyc2VGcm9tQW5jaG9yKG9wdF91cmkpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHBhcnNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBEaXNwb3NhYmxlIH0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEEgY2FjaGVkIHJlZmVyZW5jZSB0byB0aGUgY3JlYXRlIGZ1bmN0aW9uLlxuICovXG52YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTtcblxuLyoqXG4gKiBDYXNlIGluc2Vuc2l0aXZlIHN0cmluZyBNdWx0aW1hcCBpbXBsZW1lbnRhdGlvbi4gQWxsb3dzIG11bHRpcGxlIHZhbHVlcyBmb3JcbiAqIHRoZSBzYW1lIGtleSBuYW1lLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIE11bHRpTWFwIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cdFx0dGhpcy5rZXlzID0gY3JlYXRlKG51bGwpO1xuXHRcdHRoaXMudmFsdWVzID0gY3JlYXRlKG51bGwpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdmFsdWUgdG8gYSBrZXkgbmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHBhcmFtIHsqfSB2YWx1ZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRhZGQobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IG5hbWU7XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IHRoaXMudmFsdWVzW25hbWUudG9Mb3dlckNhc2UoKV0gfHwgW107XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXS5wdXNoKHZhbHVlKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhcnMgbWFwIG5hbWVzIGFuZCB2YWx1ZXMuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGNsZWFyKCkge1xuXHRcdHRoaXMua2V5cyA9IGNyZWF0ZShudWxsKTtcblx0XHR0aGlzLnZhbHVlcyA9IGNyZWF0ZShudWxsKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgbWFwIGNvbnRhaW5zIGEgdmFsdWUgdG8gdGhlIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRjb250YWlucyhuYW1lKSB7XG5cdFx0cmV0dXJuIG5hbWUudG9Mb3dlckNhc2UoKSBpbiB0aGlzLnZhbHVlcztcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMudmFsdWVzID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgYE11bHRpTWFwYCBpbnN0YW5jZSBmcm9tIHRoZSBnaXZlbiBvYmplY3QuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gb2JqXG5cdCAqIEByZXR1cm4geyFNdWx0aU1hcH1cblx0ICovXG5cdHN0YXRpYyBmcm9tT2JqZWN0KG9iaikge1xuXHRcdHZhciBtYXAgPSBuZXcgTXVsdGlNYXAoKTtcblx0XHR2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRtYXAuc2V0KGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXA7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZmlyc3QgYWRkZWQgdmFsdWUgZnJvbSBhIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcmV0dXJuIHsqfVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRnZXQobmFtZSkge1xuXHRcdHZhciB2YWx1ZXMgPSB0aGlzLnZhbHVlc1tuYW1lLnRvTG93ZXJDYXNlKCldO1xuXHRcdGlmICh2YWx1ZXMpIHtcblx0XHRcdHJldHVybiB2YWx1ZXNbMF07XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYWxsIHZhbHVlcyBmcm9tIGEga2V5IG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG5cdCAqIEByZXR1cm4ge0FycmF5LjwqPn1cblx0ICovXG5cdGdldEFsbChuYW1lKSB7XG5cdFx0cmV0dXJuIHRoaXMudmFsdWVzW25hbWUudG9Mb3dlckNhc2UoKV07XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIGlmIHRoZSBtYXAgaXMgZW1wdHksIGZhbHNlIG90aGVyd2lzZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzRW1wdHkoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2l6ZSgpID09PSAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYXJyYXkgb2Yga2V5IG5hbWVzLlxuXHQgKiBAcmV0dXJuIHtBcnJheS48c3RyaW5nPn1cblx0ICovXG5cdG5hbWVzKCkge1xuXHRcdHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnZhbHVlcykubWFwKChrZXkpID0+IHRoaXMua2V5c1trZXldKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCB2YWx1ZXMgZnJvbSBhIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRyZW1vdmUobmFtZSkge1xuXHRcdGRlbGV0ZSB0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcblx0XHRkZWxldGUgdGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIGtleSBuYW1lLiBSZWxldmFudCB0byByZXBsYWNlIHRoZSBjdXJyZW50IHZhbHVlcyB3aXRoXG5cdCAqIGEgbmV3IG9uZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHBhcmFtIHsqfSB2YWx1ZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXQobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IG5hbWU7XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IFt2YWx1ZV07XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgbWFwIGtleSBuYW1lcy5cblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0c2l6ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5uYW1lcygpLmxlbmd0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBwYXJzZWQgdmFsdWVzIGFzIGEgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy52YWx1ZXMpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE11bHRpTWFwO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBhcnJheSB9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBHZW5lcmljIHRyZWUgbm9kZSBkYXRhIHN0cnVjdHVyZSB3aXRoIGFyYml0cmFyeSBudW1iZXIgb2YgY2hpbGQgbm9kZXMuXG4gKiBAcGFyYW0ge1Z9IHZhbHVlIFZhbHVlLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmNsYXNzIFRyZWVOb2RlIHtcblxuXHRjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuXHRcdC8qKlxuXHRcdCAqIFRoZSB2YWx1ZS5cblx0XHQgKiBAcHJpdmF0ZSB7Vn1cblx0XHQgKi9cblx0XHR0aGlzLnZhbHVlXyA9IHZhbHVlO1xuXG5cdFx0LyoqXG5cdFx0ICogUmVmZXJlbmNlIHRvIHRoZSBwYXJlbnQgbm9kZSBvciBudWxsIGlmIGl0IGhhcyBubyBwYXJlbnQuXG5cdFx0ICogQHByaXZhdGUge1RyZWVOb2RlfVxuXHRcdCAqL1xuXHRcdHRoaXMucGFyZW50XyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBDaGlsZCBub2RlcyBvciBudWxsIGluIGNhc2Ugb2YgbGVhZiBub2RlLlxuXHRcdCAqIEBwcml2YXRlIHtBcnJheTwhVHJlZU5vZGU+fVxuXHRcdCAqL1xuXHRcdHRoaXMuY2hpbGRyZW5fID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBBcHBlbmRzIGEgY2hpbGQgbm9kZSB0byB0aGlzIG5vZGUuXG5cdCAqIEBwYXJhbSB7IVRyZWVOb2RlfSBjaGlsZCBPcnBoYW4gY2hpbGQgbm9kZS5cblx0ICovXG5cdGFkZENoaWxkKGNoaWxkKSB7XG5cdFx0YXNzZXJ0Q2hpbGRIYXNOb1BhcmVudChjaGlsZCk7XG5cdFx0Y2hpbGQuc2V0UGFyZW50KHRoaXMpO1xuXHRcdHRoaXMuY2hpbGRyZW5fID0gdGhpcy5jaGlsZHJlbl8gfHwgW107XG5cdFx0dGhpcy5jaGlsZHJlbl8ucHVzaChjaGlsZCk7XG5cdH1cblxuXHQvKipcblx0ICogVGVsbHMgd2hldGhlciB0aGlzIG5vZGUgaXMgdGhlIGFuY2VzdG9yIG9mIHRoZSBnaXZlbiBub2RlLlxuXHQgKiBAcGFyYW0geyFUcmVlTm9kZX0gbm9kZSBBIG5vZGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhpcyBub2RlIGlzIHRoZSBhbmNlc3RvciBvZiB7QGNvZGUgbm9kZX0uXG5cdCAqL1xuXHRjb250YWlucyhub2RlKSB7XG5cdFx0bGV0IGN1cnJlbnQgPSBub2RlLmdldFBhcmVudCgpO1xuXHRcdHdoaWxlIChjdXJyZW50KSB7XG5cdFx0XHRpZiAoY3VycmVudCA9PT0gdGhpcykge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdGN1cnJlbnQgPSBjdXJyZW50LmdldFBhcmVudCgpO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7IUFycmF5PFRyZWVOb2RlPn0gQWxsIGFuY2VzdG9yIG5vZGVzIGluIGJvdHRvbS11cCBvcmRlci5cblx0ICovXG5cdGdldEFuY2VzdG9ycygpIHtcblx0XHRsZXQgYW5jZXN0b3JzID0gW107XG5cdFx0bGV0IG5vZGUgPSB0aGlzLmdldFBhcmVudCgpO1xuXHRcdHdoaWxlIChub2RlKSB7XG5cdFx0XHRhbmNlc3RvcnMucHVzaChub2RlKTtcblx0XHRcdG5vZGUgPSBub2RlLmdldFBhcmVudCgpO1xuXHRcdH1cblx0XHRyZXR1cm4gYW5jZXN0b3JzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNoaWxkIG5vZGUgb2YgdGhpcyBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IENoaWxkIGluZGV4LlxuXHQgKiBAcmV0dXJuIHs/VHJlZU5vZGV9IFRoZSBub2RlIGF0IHRoZSBnaXZlbiBpbmRleFxuXHQgKiBvciBudWxsIGlmIG5vdCBmb3VuZC5cblx0ICovXG5cdGdldENoaWxkQXQoaW5kZXgpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRDaGlsZHJlbigpW2luZGV4XSB8fCBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4gez9BcnJheTwhVHJlZU5vZGU+fSBDaGlsZCBub2RlcyBvciBudWxsIGluIGNhc2Ugb2YgbGVhZiBub2RlLlxuXHQgKi9cblx0Z2V0Q2hpbGRyZW4oKSB7XG5cdFx0cmV0dXJuIHRoaXMuY2hpbGRyZW5fIHx8IFRyZWVOb2RlLkVNUFRZX0FSUkFZO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBjaGlsZHJlbi5cblx0ICovXG5cdGdldENoaWxkQ291bnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0Q2hpbGRyZW4oKS5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGFuY2VzdG9ycyBvZiB0aGUgbm9kZS5cblx0ICovXG5cdGdldERlcHRoKCkge1xuXHRcdGxldCBkZXB0aCA9IDA7XG5cdFx0bGV0IG5vZGUgPSB0aGlzO1xuXHRcdHdoaWxlIChub2RlLmdldFBhcmVudCgpKSB7XG5cdFx0XHRkZXB0aCsrO1xuXHRcdFx0bm9kZSA9IG5vZGUuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiBkZXB0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHs/VHJlZU5vZGV9IFBhcmVudCBub2RlIG9yIG51bGwgaWYgaXQgaGFzIG5vIHBhcmVudC5cblx0ICovXG5cdGdldFBhcmVudCgpIHtcblx0XHRyZXR1cm4gdGhpcy5wYXJlbnRfO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4geyFUcmVlTm9kZX0gVGhlIHJvb3Qgb2YgdGhlIHRyZWUgc3RydWN0dXJlLCBpLmUuIHRoZSBmYXJ0aGVzdFxuXHQgKiBhbmNlc3RvciBvZiB0aGUgbm9kZSBvciB0aGUgbm9kZSBpdHNlbGYgaWYgaXQgaGFzIG5vIHBhcmVudHMuXG5cdCAqL1xuXHRnZXRSb290KCkge1xuXHRcdGxldCByb290ID0gdGhpcztcblx0XHR3aGlsZSAocm9vdC5nZXRQYXJlbnQoKSkge1xuXHRcdFx0cm9vdCA9IHJvb3QuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiByb290O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHZhbHVlLlxuXHQgKiBAcmV0dXJuIHtWfSBUaGUgdmFsdWUuXG5cdCAqL1xuXHRnZXRWYWx1ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy52YWx1ZV87XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBpcyBhIGxlYWYgbm9kZS5cblx0ICovXG5cdGlzTGVhZigpIHtcblx0XHRyZXR1cm4gIXRoaXMuZ2V0Q2hpbGRDb3VudCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGdpdmVuIGNoaWxkIG5vZGUgb2YgdGhpcyBub2RlLlxuXHQgKiBAcGFyYW0ge1RyZWVOb2RlfSBjaGlsZCBUaGUgbm9kZSB0byByZW1vdmUuXG5cdCAqIEByZXR1cm4ge1RyZWVOb2RlfSBUaGUgcmVtb3ZlZCBub2RlIGlmIGFueSwgbnVsbCBvdGhlcndpc2UuXG5cdCAqL1xuXHRyZW1vdmVDaGlsZChjaGlsZCkge1xuXHRcdGlmIChhcnJheS5yZW1vdmUodGhpcy5nZXRDaGlsZHJlbigpLCBjaGlsZCkpIHtcblx0XHRcdHJldHVybiBjaGlsZDtcblx0XHR9XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgcGFyZW50IG5vZGUgb2YgdGhpcyBub2RlLiBUaGUgY2FsbGVycyBtdXN0IGVuc3VyZSB0aGF0IHRoZVxuXHQgKiBwYXJlbnQgbm9kZSBhbmQgb25seSB0aGF0IGhhcyB0aGlzIG5vZGUgYW1vbmcgaXRzIGNoaWxkcmVuLlxuXHQgKiBAcGFyYW0ge1RyZWVOb2RlfSBwYXJlbnQgVGhlIHBhcmVudCB0byBzZXQuIElmIG51bGwsIHRoZSBub2RlIHdpbGwgYmVcblx0ICogZGV0YWNoZWQgZnJvbSB0aGUgdHJlZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0c2V0UGFyZW50KHBhcmVudCkge1xuXHRcdHRoaXMucGFyZW50XyA9IHBhcmVudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUcmF2ZXJzZXMgdGhlIHN1YnRyZWUuIFRoZSBmaXJzdCBjYWxsYmFjayBzdGFydHMgd2l0aCB0aGlzIG5vZGUsXG5cdCAqIGFuZCB2aXNpdHMgdGhlIGRlc2NlbmRhbnQgbm9kZXMgZGVwdGgtZmlyc3QsIGluIHByZW9yZGVyLlxuXHQgKiBUaGUgc2Vjb25kIGNhbGxiYWNrLCBzdGFydHMgd2l0aCBkZWVwZXN0IGNoaWxkIHRoZW4gdmlzaXRzXG5cdCAqIHRoZSBhbmNlc3RvciBub2RlcyBkZXB0aC1maXJzdCwgaW4gcG9zdG9yZGVyLiBFLmcuXG5cdCAqXG5cdCAqICBcdCBBXG5cdCAqICAgIC8gXFxcblx0ICogICBCICAgQ1xuXHQgKiAgLyAgIC8gXFxcblx0ICogRCAgIEUgICBGXG5cdCAqXG5cdCAqIHByZW9yZGVyIC0+IFsnQScsICdCJywgJ0QnLCAnQycsICdFJywgJ0YnXVxuXHQgKiBwb3N0b3JkZXIgLT4gWydEJywgJ0InLCAnRScsICdGJywgJ0MnLCAnQSddXG5cdCAqXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb249fSBvcHRfcHJlb3JkZXJGbiBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSB3aGVuIHZpc2l0aW5nIGEgbm9kZS5cblx0ICogQHBhcmFtIHtmdW5jdGlvbj19IG9wdF9wb3N0b3JkZXJGbiBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSBiZWZvcmUgbGVhdmluZyBhIG5vZGUuXG5cdCAqL1xuXHR0cmF2ZXJzZShvcHRfcHJlb3JkZXJGbiwgb3B0X3Bvc3RvcmRlckZuKSB7XG5cdFx0aWYgKG9wdF9wcmVvcmRlckZuKSB7XG5cdFx0XHRvcHRfcHJlb3JkZXJGbih0aGlzKTtcblx0XHR9XG5cdFx0dGhpcy5nZXRDaGlsZHJlbigpLmZvckVhY2goKGNoaWxkKSA9PiBjaGlsZC50cmF2ZXJzZShvcHRfcHJlb3JkZXJGbiwgb3B0X3Bvc3RvcmRlckZuKSk7XG5cdFx0aWYgKG9wdF9wb3N0b3JkZXJGbikge1xuXHRcdFx0b3B0X3Bvc3RvcmRlckZuKHRoaXMpO1xuXHRcdH1cblx0fVxuXG59XG5cbi8qKlxuICogQ29uc3RhbnQgZm9yIGVtcHR5IGFycmF5IHRvIGF2b2lkIHVubmVjZXNzYXJ5IGFsbG9jYXRpb25zLlxuICogQHByaXZhdGVcbiAqL1xuVHJlZU5vZGUuRU1QVFlfQVJSQVkgPSBbXTtcblxuLyoqXG4gKiBBc3NlcnRzIHRoYXQgY2hpbGQgaGFzIG5vIHBhcmVudC5cbiAqIEBwYXJhbSB7VHJlZU5vZGV9IGNoaWxkIEEgY2hpbGQuXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBhc3NlcnRDaGlsZEhhc05vUGFyZW50ID0gZnVuY3Rpb24oY2hpbGQpIHtcblx0aWYgKGNoaWxkLmdldFBhcmVudCgpKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgYWRkIGNoaWxkIHdpdGggcGFyZW50LicpO1xuXHR9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBUcmVlTm9kZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgaXNEZWYsIHN0cmluZyB9IGZyb20gJ21ldGFsJztcbmltcG9ydCBwYXJzZSBmcm9tICcuL3BhcnNlJztcbmltcG9ydCB7IE11bHRpTWFwIH0gZnJvbSAnbWV0YWwtc3RydWN0cyc7XG5cbnZhciBwYXJzZUZuXyA9IHBhcnNlO1xuXG5jbGFzcyBVcmkge1xuXG5cdC8qKlxuXHQgKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHNldHRlcnMgYW5kIGdldHRlcnMgZm9yIHRoZSBwYXJ0cyBvZiB0aGUgVVJJLlxuXHQgKiBUaGUgZm9sbG93aW5nIGZpZ3VyZSBkaXNwbGF5cyBhbiBleGFtcGxlIFVSSXMgYW5kIHRoZWlyIGNvbXBvbmVudCBwYXJ0cy5cblx0ICpcblx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aFxuXHQgKlx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIzilIDilIDilIDilLTilIDilIDilIDilIDilJBcblx0ICpcdCAgYWJjOi8vZXhhbXBsZS5jb206MTIzL3BhdGgvZGF0YT9rZXk9dmFsdWUjZnJhZ2lkMVxuXHQgKlx0ICDilJTilKzilJggICDilJTilIDilIDilIDilIDilKzilIDilIDilIDilIDilJgg4pSU4pSs4pSYICAgICAgICAgICDilJTilIDilIDilIDilKzilIDilIDilIDilJgg4pSU4pSA4pSA4pSs4pSA4pSA4pSYXG5cdCAqIHByb3RvY29sICBob3N0bmFtZSAgcG9ydCAgICAgICAgICAgIHNlYXJjaCAgICBoYXNoXG5cdCAqICAgICAgICAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuXHQgKiAgICAgICAgICAgICAgICBob3N0XG5cdCAqXG5cdCAqIEBwYXJhbSB7Kj19IG9wdF91cmkgT3B0aW9uYWwgc3RyaW5nIFVSSSB0byBwYXJzZVxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9wdF91cmkgPSAnJykge1xuXHRcdHRoaXMudXJsID0gVXJpLnBhcnNlKHRoaXMubWF5YmVBZGRQcm90b2NvbEFuZEhvc3RuYW1lXyhvcHRfdXJpKSk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBwYXJhbWV0ZXJzIHRvIHVyaSBmcm9tIGEgPGNvZGU+TXVsdGlNYXA8L2NvZGU+IGFzIHNvdXJjZS5cblx0ICogQHBhcmFtIHtNdWx0aU1hcH0gbXVsdGltYXAgVGhlIDxjb2RlPk11bHRpTWFwPC9jb2RlPiBjb250YWluaW5nIHRoZVxuXHQgKiAgIHBhcmFtZXRlcnMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkUGFyYW1ldGVyc0Zyb21NdWx0aU1hcChtdWx0aW1hcCkge1xuXHRcdG11bHRpbWFwLm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuXHRcdFx0bXVsdGltYXAuZ2V0QWxsKG5hbWUpLmZvckVhY2goKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB0aGUgdmFsdWUgb2YgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlcnMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHBhcmFtZXRlciB0byBzZXQuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZS4gV2lsbCBiZSBleHBsaWNpdGx5IGNhc3RlZCB0byBTdHJpbmcuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFBhcmFtZXRlclZhbHVlKG5hbWUsIHZhbHVlKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdGlmIChpc0RlZih2YWx1ZSkpIHtcblx0XHRcdHZhbHVlID0gU3RyaW5nKHZhbHVlKTtcblx0XHR9XG5cdFx0dGhpcy5xdWVyeS5hZGQobmFtZSwgdmFsdWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIHZhbHVlcyBvZiB0aGUgbmFtZWQgcXVlcnkgcGFyYW1ldGVyLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFBhcmFtZXRlclZhbHVlcyhuYW1lLCB2YWx1ZXMpIHtcblx0XHR2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBFbnN1cmVzIHF1ZXJ5IGludGVybmFsIG1hcCBpcyBpbml0aWFsaXplZCBhbmQgc3luY2VkIHdpdGggaW5pdGlhbCB2YWx1ZVxuXHQgKiBleHRyYWN0ZWQgZnJvbSBVUkkgc2VhcmNoIHBhcnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCkge1xuXHRcdGlmICh0aGlzLnF1ZXJ5KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMucXVlcnkgPSBuZXcgTXVsdGlNYXAoKTtcblx0XHR2YXIgc2VhcmNoID0gdGhpcy51cmwuc2VhcmNoO1xuXHRcdGlmIChzZWFyY2gpIHtcblx0XHRcdHNlYXJjaC5zdWJzdHJpbmcoMSkuc3BsaXQoJyYnKS5mb3JFYWNoKChwYXJhbSkgPT4ge1xuXHRcdFx0XHR2YXIgW2tleSwgdmFsdWVdID0gcGFyYW0uc3BsaXQoJz0nKTtcblx0XHRcdFx0aWYgKGlzRGVmKHZhbHVlKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gVXJpLnVybERlY29kZSh2YWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShrZXksIHZhbHVlKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBoYXNoIHBhcnQgb2YgdXJpLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRIYXNoKCkge1xuXHRcdHJldHVybiB0aGlzLnVybC5oYXNoIHx8ICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGhvc3QgcGFydCBvZiB1cmkuIEUuZy4gPGNvZGU+W2hvc3RuYW1lXTpbcG9ydF08L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRIb3N0KCkge1xuXHRcdHZhciBob3N0ID0gdGhpcy5nZXRIb3N0bmFtZSgpO1xuXHRcdGlmIChob3N0KSB7XG5cdFx0XHR2YXIgcG9ydCA9IHRoaXMuZ2V0UG9ydCgpO1xuXHRcdFx0aWYgKHBvcnQgJiYgcG9ydCAhPT0gJzgwJykge1xuXHRcdFx0XHRob3N0ICs9ICc6JyArIHBvcnQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBob3N0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGhvc3RuYW1lIHBhcnQgb2YgdXJpIHdpdGhvdXQgcHJvdG9jb2wgYW5kIHBvcnQuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldEhvc3RuYW1lKCkge1xuXHRcdHZhciBob3N0bmFtZSA9IHRoaXMudXJsLmhvc3RuYW1lO1xuXHRcdGlmIChob3N0bmFtZSA9PT0gVXJpLkhPU1ROQU1FX1BMQUNFSE9MREVSKSB7XG5cdFx0XHRyZXR1cm4gJyc7XG5cdFx0fVxuXHRcdHJldHVybiBob3N0bmFtZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBvcmlnaW4gcGFydCBvZiB1cmkuIEUuZy4gPGNvZGU+aHR0cDovL1tob3N0bmFtZV06W3BvcnRdPC9jb2RlPi5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0T3JpZ2luKCkge1xuXHRcdHZhciBob3N0ID0gdGhpcy5nZXRIb3N0KCk7XG5cdFx0aWYgKGhvc3QpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldFByb3RvY29sKCkgKyAnLy8nICsgaG9zdDtcblx0XHR9XG5cdFx0cmV0dXJuICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGZpcnN0IHZhbHVlIGZvciBhIGdpdmVuIHBhcmFtZXRlciBvciB1bmRlZmluZWQgaWYgdGhlIGdpdmVuXG5cdCAqIHBhcmFtZXRlciBuYW1lIGRvZXMgbm90IGFwcGVhciBpbiB0aGUgcXVlcnkgc3RyaW5nLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1OYW1lIFVuZXNjYXBlZCBwYXJhbWV0ZXIgbmFtZS5cblx0ICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gVGhlIGZpcnN0IHZhbHVlIGZvciBhIGdpdmVuIHBhcmFtZXRlciBvclxuXHQgKiAgIHVuZGVmaW5lZCBpZiB0aGUgZ2l2ZW4gcGFyYW1ldGVyIG5hbWUgZG9lcyBub3QgYXBwZWFyIGluIHRoZSBxdWVyeVxuXHQgKiAgIHN0cmluZy5cblx0ICovXG5cdGdldFBhcmFtZXRlclZhbHVlKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0cmV0dXJuIHRoaXMucXVlcnkuZ2V0KG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHZhbHVlPGI+czwvYj4gZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyIGFzIGEgbGlzdCBvZiBkZWNvZGVkXG5cdCAqIHF1ZXJ5IHBhcmFtZXRlciB2YWx1ZXMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBwYXJhbWV0ZXIgdG8gZ2V0IHZhbHVlcyBmb3IuXG5cdCAqIEByZXR1cm4geyFBcnJheTw/Pn0gVGhlIHZhbHVlcyBmb3IgYSBnaXZlbiBwYXJhbWV0ZXIgYXMgYSBsaXN0IG9mIGRlY29kZWRcblx0ICogICBxdWVyeSBwYXJhbWV0ZXIgdmFsdWVzLlxuXHQgKi9cblx0Z2V0UGFyYW1ldGVyVmFsdWVzKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0cmV0dXJuIHRoaXMucXVlcnkuZ2V0QWxsKG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIG5hbWU8Yj5zPC9iPiBvZiB0aGUgcGFyYW1ldGVycy5cblx0ICogQHJldHVybiB7IUFycmF5PHN0cmluZz59IFRoZSBuYW1lcyBmb3IgdGhlIHBhcmFtZXRlcnMgYXMgYSBsaXN0IG9mXG5cdCAqICAgc3RyaW5ncy5cblx0ICovXG5cdGdldFBhcmFtZXRlck5hbWVzKCkge1xuXHRcdHRoaXMuZW5zdXJlUXVlcnlJbml0aWFsaXplZF8oKTtcblx0XHRyZXR1cm4gdGhpcy5xdWVyeS5uYW1lcygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGZ1bmN0aW9uIGN1cnJlbnRseSBiZWluZyB1c2VkIHRvIHBhcnNlIFVSSXMuXG5cdCAqIEByZXR1cm4geyFmdW5jdGlvbigpfVxuXHQgKi9cblx0c3RhdGljIGdldFBhcnNlRm4oKSB7XG5cdFx0cmV0dXJuIHBhcnNlRm5fO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHBhdGhuYW1lIHBhcnQgb2YgdXJpLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRQYXRobmFtZSgpIHtcblx0XHRyZXR1cm4gdGhpcy51cmwucGF0aG5hbWU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcG9ydCBudW1iZXIgcGFydCBvZiB1cmkgYXMgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRQb3J0KCkge1xuXHRcdHJldHVybiB0aGlzLnVybC5wb3J0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHByb3RvY29sIHBhcnQgb2YgdXJpLiBFLmcuIDxjb2RlPmh0dHA6PC9jb2RlPi5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0UHJvdG9jb2woKSB7XG5cdFx0cmV0dXJuIHRoaXMudXJsLnByb3RvY29sO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHNlYXJjaCBwYXJ0IG9mIHVyaS4gU2VhcmNoIHZhbHVlIGlzIHJldHJpZXZlZCBmcm9tIHF1ZXJ5XG5cdCAqIHBhcmFtZXRlcnMuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldFNlYXJjaCgpIHtcblx0XHR2YXIgc2VhcmNoID0gJyc7XG5cdFx0dmFyIHF1ZXJ5c3RyaW5nID0gJyc7XG5cdFx0dGhpcy5nZXRQYXJhbWV0ZXJOYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcblx0XHRcdHRoaXMuZ2V0UGFyYW1ldGVyVmFsdWVzKG5hbWUpLmZvckVhY2goKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHF1ZXJ5c3RyaW5nICs9IG5hbWU7XG5cdFx0XHRcdGlmIChpc0RlZih2YWx1ZSkpIHtcblx0XHRcdFx0XHRxdWVyeXN0cmluZyArPSAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHF1ZXJ5c3RyaW5nICs9ICcmJztcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHRcdHF1ZXJ5c3RyaW5nID0gcXVlcnlzdHJpbmcuc2xpY2UoMCwgLTEpO1xuXHRcdGlmIChxdWVyeXN0cmluZykge1xuXHRcdFx0c2VhcmNoICs9ICc/JyArIHF1ZXJ5c3RyaW5nO1xuXHRcdH1cblx0XHRyZXR1cm4gc2VhcmNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB1cmkgY29udGFpbnMgdGhlIHBhcmFtZXRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGhhc1BhcmFtZXRlcihuYW1lKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdHJldHVybiB0aGlzLnF1ZXJ5LmNvbnRhaW5zKG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1ha2VzIHRoaXMgVVJMIHVuaXF1ZSBieSBhZGRpbmcgYSByYW5kb20gcGFyYW0gdG8gaXQuIFVzZWZ1bCBmb3IgYXZvaWRpbmdcblx0ICogY2FjaGUuXG5cdCAqL1xuXHRtYWtlVW5pcXVlKCkge1xuXHRcdHRoaXMuc2V0UGFyYW1ldGVyVmFsdWUoVXJpLlJBTkRPTV9QQVJBTSwgc3RyaW5nLmdldFJhbmRvbVN0cmluZygpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBhZGRzIHByb3RvY29sIGFuZCBhIGhvc3RuYW1lIHBsYWNlaG9sZGVyIG9uIGEgcGFyaWFsIFVSSSBpZiBuZWVkZWQuXG5cdCAqIFJlbGV2ZW50IGZvciBjb21wYXRpYmlsaXR5IHdpdGggPGNvZGU+VVJMPC9jb2RlPiBuYXRpdmUgb2JqZWN0LlxuXHQgKiBAcGFyYW0ge3N0cmluZz19IG9wdF91cmlcblx0ICogQHJldHVybiB7c3RyaW5nfSBVUkkgd2l0aCBwcm90b2NvbCBhbmQgaG9zdG5hbWUgcGxhY2Vob2xkZXIuXG5cdCAqL1xuXHRtYXliZUFkZFByb3RvY29sQW5kSG9zdG5hbWVfKG9wdF91cmkpIHtcblx0XHR2YXIgdXJsID0gb3B0X3VyaTtcblx0XHRpZiAob3B0X3VyaS5pbmRleE9mKCc6Ly8nKSA9PT0gLTEgJiZcblx0XHRcdG9wdF91cmkuaW5kZXhPZignamF2YXNjcmlwdDonKSAhPT0gMCkgeyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuXHRcdFx0dXJsID0gVXJpLkRFRkFVTFRfUFJPVE9DT0w7XG5cdFx0XHRpZiAob3B0X3VyaVswXSAhPT0gJy8nIHx8IG9wdF91cmlbMV0gIT09ICcvJykge1xuXHRcdFx0XHR1cmwgKz0gJy8vJztcblx0XHRcdH1cblxuXHRcdFx0c3dpdGNoIChvcHRfdXJpLmNoYXJBdCgwKSkge1xuXHRcdFx0XHRjYXNlICcuJzpcblx0XHRcdFx0Y2FzZSAnPyc6XG5cdFx0XHRcdGNhc2UgJyMnOlxuXHRcdFx0XHRcdHVybCArPSBVcmkuSE9TVE5BTUVfUExBQ0VIT0xERVI7XG5cdFx0XHRcdFx0dXJsICs9ICcvJztcblx0XHRcdFx0XHR1cmwgKz0gb3B0X3VyaTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnJzpcblx0XHRcdFx0Y2FzZSAnLyc6XG5cdFx0XHRcdFx0aWYgKG9wdF91cmlbMV0gIT09ICcvJykge1xuXHRcdFx0XHRcdFx0dXJsICs9IFVyaS5IT1NUTkFNRV9QTEFDRUhPTERFUjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dXJsICs9IG9wdF91cmk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0dXJsICs9IG9wdF91cmk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB1cmw7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuXHQgKiBAcGFyYW0geyo9fSBvcHRfdXJpIE9wdGlvbmFsIHN0cmluZyBVUkkgdG8gcGFyc2Vcblx0ICovXG5cdHN0YXRpYyBwYXJzZShvcHRfdXJpKSB7XG5cdFx0cmV0dXJuIHBhcnNlRm5fKG9wdF91cmkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIHBhcmFtZXRlciB0byByZW1vdmUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHJlbW92ZVBhcmFtZXRlcihuYW1lKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdHRoaXMucXVlcnkucmVtb3ZlKG5hbWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdW5pcXVlbmVzcyBwYXJhbWV0ZXIgb2YgdGhlIHVyaS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0cmVtb3ZlVW5pcXVlKCkge1xuXHRcdHRoaXMucmVtb3ZlUGFyYW1ldGVyKFVyaS5SQU5ET01fUEFSQU0pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGhhc2guXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldEhhc2goaGFzaCkge1xuXHRcdHRoaXMudXJsLmhhc2ggPSBoYXNoO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGhvc3RuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaG9zdG5hbWVcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0SG9zdG5hbWUoaG9zdG5hbWUpIHtcblx0XHR0aGlzLnVybC5ob3N0bmFtZSA9IGhvc3RuYW1lO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBuYW1lZCBxdWVyeSBwYXJhbWV0ZXJzLCBjbGVhcmluZyBwcmV2aW91cyB2YWx1ZXNcblx0ICogZm9yIHRoYXQga2V5LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhcmFtZXRlclZhbHVlKG5hbWUsIHZhbHVlKSB7XG5cdFx0dGhpcy5yZW1vdmVQYXJhbWV0ZXIobmFtZSk7XG5cdFx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShuYW1lLCB2YWx1ZSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdmFsdWVzIG9mIHRoZSBuYW1lZCBxdWVyeSBwYXJhbWV0ZXJzLCBjbGVhcmluZyBwcmV2aW91cyB2YWx1ZXNcblx0ICogZm9yIHRoYXQga2V5LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhcmFtZXRlclZhbHVlcyhuYW1lLCB2YWx1ZXMpIHtcblx0XHR0aGlzLnJlbW92ZVBhcmFtZXRlcihuYW1lKTtcblx0XHR2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwYXRobmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGhuYW1lXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhdGhuYW1lKHBhdGhuYW1lKSB7XG5cdFx0dGhpcy51cmwucGF0aG5hbWUgPSBwYXRobmFtZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwb3J0IG51bWJlci5cblx0ICogQHBhcmFtIHsqfSBwb3J0IFBvcnQgbnVtYmVyLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXRQb3J0KHBvcnQpIHtcblx0XHR0aGlzLnVybC5wb3J0ID0gcG9ydDtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgdXNlZCBmb3IgcGFyc2luZyB0aGUgb3JpZ2luYWwgc3RyaW5nIHVyaVxuXHQgKiBpbnRvIGFuIG9iamVjdC5cblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gcGFyc2VGblxuXHQgKi9cblx0c3RhdGljIHNldFBhcnNlRm4ocGFyc2VGbikge1xuXHRcdHBhcnNlRm5fID0gcGFyc2VGbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwcm90b2NvbC4gSWYgbWlzc2luZyA8Y29kZT5odHRwOjwvY29kZT4gaXMgdXNlZCBhcyBkZWZhdWx0LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcHJvdG9jb2xcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0UHJvdG9jb2wocHJvdG9jb2wpIHtcblx0XHR0aGlzLnVybC5wcm90b2NvbCA9IHByb3RvY29sO1xuXHRcdGlmICh0aGlzLnVybC5wcm90b2NvbFt0aGlzLnVybC5wcm90b2NvbC5sZW5ndGggLSAxXSAhPT0gJzonKSB7XG5cdFx0XHR0aGlzLnVybC5wcm90b2NvbCArPSAnOic7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZyBmb3JtIG9mIHRoZSB1cmwuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0dG9TdHJpbmcoKSB7XG5cdFx0dmFyIGhyZWYgPSAnJztcblx0XHR2YXIgaG9zdCA9IHRoaXMuZ2V0SG9zdCgpO1xuXHRcdGlmIChob3N0KSB7XG5cdFx0XHRocmVmICs9IHRoaXMuZ2V0UHJvdG9jb2woKSArICcvLyc7XG5cdFx0fVxuXHRcdGhyZWYgKz0gaG9zdCArIHRoaXMuZ2V0UGF0aG5hbWUoKSArIHRoaXMuZ2V0U2VhcmNoKCkgKyB0aGlzLmdldEhhc2goKTtcblx0XHRyZXR1cm4gaHJlZjtcblx0fVxuXG5cdC8qKlxuXHQgKiBKb2lucyB0aGUgZ2l2ZW4gcGF0aHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aFxuXHQgKiBAcGFyYW0gey4uLnN0cmluZ30gLi4ucGF0aHMgQW55IG51bWJlciBvZiBwYXRocyB0byBiZSBqb2luZWQgd2l0aCB0aGUgYmFzZSB1cmwuXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBqb2luUGF0aHMoYmFzZVBhdGgsIC4uLnBhdGhzKSB7XG5cdFx0aWYgKGJhc2VQYXRoLmNoYXJBdChiYXNlUGF0aC5sZW5ndGggLSAxKSA9PT0gJy8nKSB7XG5cdFx0XHRiYXNlUGF0aCA9IGJhc2VQYXRoLnN1YnN0cmluZygwLCBiYXNlUGF0aC5sZW5ndGggLSAxKTtcblx0XHR9XG5cdFx0cGF0aHMgPSBwYXRocy5tYXAocGF0aCA9PiBwYXRoLmNoYXJBdCgwKSA9PT0gJy8nID8gcGF0aC5zdWJzdHJpbmcoMSkgOiBwYXRoKTtcblx0XHRyZXR1cm4gW2Jhc2VQYXRoXS5jb25jYXQocGF0aHMpLmpvaW4oJy8nKS5yZXBsYWNlKC9cXC8kLywgJycpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVSTC1kZWNvZGVzIHRoZSBzdHJpbmcuIFdlIG5lZWQgdG8gc3BlY2lhbGx5IGhhbmRsZSAnKydzIGJlY2F1c2Vcblx0ICogdGhlIGphdmFzY3JpcHQgbGlicmFyeSBkb2Vzbid0IGNvbnZlcnQgdGhlbSB0byBzcGFjZXMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0byB1cmwgZGVjb2RlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBkZWNvZGVkIHtAY29kZSBzdHJ9LlxuXHQgKi9cblx0c3RhdGljIHVybERlY29kZShzdHIpIHtcblx0XHRyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0ci5yZXBsYWNlKC9cXCsvZywgJyAnKSk7XG5cdH1cblxufVxuXG4vKipcbiAqIERlZmF1bHQgcHJvdG9jb2wgdmFsdWUuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGRlZmF1bHQgaHR0cDpcbiAqIEBzdGF0aWNcbiAqL1xuY29uc3QgaXNTZWN1cmUgPSAoKSA9PlxuXHQodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR3aW5kb3cubG9jYXRpb24gJiZcblx0XHR3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgJiZcblx0XHR3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wuaW5kZXhPZignaHR0cHMnKSA9PT0gMCk7XG5cblVyaS5ERUZBVUxUX1BST1RPQ09MID0gaXNTZWN1cmUoKSA/ICdodHRwczonIDogJ2h0dHA6JztcblxuLyoqXG4gKiBIb3N0bmFtZSBwbGFjZWhvbGRlci4gUmVsZXZhbnQgdG8gaW50ZXJuYWwgdXNhZ2Ugb25seS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cblVyaS5IT1NUTkFNRV9QTEFDRUhPTERFUiA9ICdob3N0bmFtZScgKyBEYXRlLm5vdygpO1xuXG4vKipcbiAqIE5hbWUgdXNlZCBieSB0aGUgcGFyYW0gZ2VuZXJhdGVkIGJ5IGBtYWtlVW5pcXVlYC5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cblVyaS5SQU5ET01fUEFSQU0gPSAnengnO1xuXG5leHBvcnQgZGVmYXVsdCBVcmk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGV4aXREb2N1bWVudCB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBzdGF0aWMgdXRpbGl0eSBmdW5jdGlvbnMuXG4gKiBAY29uc3RcbiAqL1xuY2xhc3MgdXRpbHMge1xuXG5cdC8qKlxuXHQgKiBDb3BpZXMgYXR0cmlidXRlcyBmb3JtIHNvdXJjZSBub2RlIHRvIHRhcmdldCBub2RlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgY29weU5vZGVBdHRyaWJ1dGVzKHNvdXJjZSwgdGFyZ2V0KSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoc291cmNlLmF0dHJpYnV0ZXMpLmZvckVhY2goKGF0dHJpYnV0ZSkgPT4gdGFyZ2V0LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUubmFtZSwgYXR0cmlidXRlLnZhbHVlKSk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY3VycmVudCBicm93c2VyIHBhdGggaW5jbHVkaW5nIGhhc2hiYW5nLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0Q3VycmVudEJyb3dzZXJQYXRoKCkge1xuXHRcdHJldHVybiB0aGlzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCkgKyBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGN1cnJlbnQgYnJvd3NlciBwYXRoIGV4Y2x1ZGluZyBoYXNoYmFuZy5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCkge1xuXHRcdHJldHVybiBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnNlYXJjaDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBnaXZlbiBub2RlIG9mZnNldCBjb29yZGluYXRlcy5cblx0ICogQHJldHVybiB7IW9iamVjdH1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldE5vZGVPZmZzZXQobm9kZSkge1xuXHRcdGxldCBbb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wXSA9IFswLCAwXTtcblx0XHRkbyB7XG5cdFx0XHRvZmZzZXRMZWZ0ICs9IG5vZGUub2Zmc2V0TGVmdDtcblx0XHRcdG9mZnNldFRvcCArPSBub2RlLm9mZnNldFRvcDtcblx0XHRcdG5vZGUgPSBub2RlLm9mZnNldFBhcmVudDtcblx0XHR9IHdoaWxlIChub2RlKTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0b2Zmc2V0TGVmdCxcblx0XHRcdG9mZnNldFRvcFxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgdGhlIHBhdGggcGFydCBvZiBhbiB1cmwuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXRVcmxQYXRoKHVybCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHVybCk7XG5cdFx0cmV0dXJuIHVyaS5nZXRQYXRobmFtZSgpICsgdXJpLmdldFNlYXJjaCgpICsgdXJpLmdldEhhc2goKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyB0aGUgcGF0aCBwYXJ0IG9mIGFuIHVybCB3aXRob3V0IGhhc2hiYW5nLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0VXJsUGF0aFdpdGhvdXRIYXNoKHVybCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHVybCk7XG5cdFx0cmV0dXJuIHVyaS5nZXRQYXRobmFtZSgpICsgdXJpLmdldFNlYXJjaCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIHRoZSBwYXRoIHBhcnQgb2YgYW4gdXJsIHdpdGhvdXQgaGFzaGJhbmcgYW5kIHF1ZXJ5IHNlYXJjaC5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaCh1cmwpIHtcblx0XHR2YXIgdXJpID0gbmV3IFVyaSh1cmwpO1xuXHRcdHJldHVybiB1cmkuZ2V0UGF0aG5hbWUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdXJsIGlzIGluIHRoZSBzYW1lIGJyb3dzZXIgY3VycmVudCB1cmwgZXhjbHVkaW5nIHRoZSBoYXNoYmFuZy5cblx0ICogQHBhcmFtICB7IXN0cmluZ30gdXJsXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBpc0N1cnJlbnRCcm93c2VyUGF0aCh1cmwpIHtcblx0XHRpZiAodXJsKSB7XG5cdFx0XHRjb25zdCBjdXJyZW50QnJvd3NlclBhdGggPSB0aGlzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCk7XG5cdFx0XHQvLyB0aGUgZ2V0VXJsUGF0aCB3aWxsIGNyZWF0ZSBhIFVyaSBhbmQgd2lsbCBub3JtYWxpemUgdGhlIHBhdGggYW5kXG5cdFx0XHQvLyByZW1vdmUgdGhlIHRyYWlsbGluZyAnLycgZm9yIHByb3Blcmx5IGNvbXBhcmluZyBwYXRocy5cblx0XHRcdHJldHVybiB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2godXJsKSA9PT0gdGhpcy5nZXRVcmxQYXRoKGN1cnJlbnRCcm93c2VyUGF0aCk7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRydWUgaWYgSFRNTDUgSGlzdG9yeSBhcGkgaXMgc3VwcG9ydGVkLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgaXNIdG1sNUhpc3RvcnlTdXBwb3J0ZWQoKSB7XG5cdFx0cmV0dXJuICEhKGdsb2JhbHMud2luZG93Lmhpc3RvcnkgJiYgZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBhIGdpdmVuIHVybCBpcyBhIHZhbGlkIGh0dHAocykgdXJpIGFuZCByZXR1cm5zIHRoZSBmb3JtZWQgVXJpXG5cdCAqIG9yIGZhbHNlIGlmIHRoZSBwYXJzaW5nIGZhaWxlZFxuXHQgKiBAcmV0dXJuIHtVcml8Ym9vbGVhbn1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGlzV2ViVXJpKHVybCkge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gbmV3IFVyaSh1cmwpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJHtlcnIubWVzc2FnZX0gJHt1cmx9YCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGF0dHJpYnV0ZXMgZm9ybSBub2RlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgY2xlYXJOb2RlQXR0cmlidXRlcyhub2RlKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobm9kZS5hdHRyaWJ1dGVzKS5mb3JFYWNoKChhdHRyaWJ1dGUpID0+IG5vZGUucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZS5uYW1lKSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlIGVsZW1lbnRzIGZyb20gdGhlIGRvY3VtZW50LlxuXHQgKiBAcGFyYW0geyFBcnJheTxFbGVtZW50Pn0gZWxlbWVudHNcblx0ICovXG5cdHN0YXRpYyByZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudChlbGVtZW50cykge1xuXHRcdGVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IGV4aXREb2N1bWVudChlbGVtZW50KSk7XG5cdH1cblxuXHQvKipcblx0KiBSZW1vdmVzIHRyYWlsaW5nIHNsYXNoIGluIHBhdGguXG5cdCogQHBhcmFtIHshc3RyaW5nfVxuXHQqIEByZXR1cm4ge3N0cmluZ31cblx0Ki9cblx0c3RhdGljIHJlbW92ZVBhdGhUcmFpbGluZ1NsYXNoKHBhdGgpIHtcblx0XHR2YXIgbGVuZ3RoID0gcGF0aCA/IHBhdGgubGVuZ3RoIDogMDtcblx0XHRpZiAobGVuZ3RoID4gMSAmJiBwYXRoW2xlbmd0aCAtIDFdID09PSAnLycpIHtcblx0XHRcdHBhdGggPSBwYXRoLnN1YnN0cigwLCBsZW5ndGggLSAxKTtcblx0XHR9XG5cdFx0cmV0dXJuIHBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIHJhbmRvbSBzdWZmaXggdG8gdGhlIGhyZWYgYXR0cmlidXRlIG9mIHRoZSBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFlbGVtZW50fSBlbGVtZW50XG5cdCAqIEByZXR1cm4ge2VsZW1lbnR9XG5cdCAqL1xuXHRzdGF0aWMgc2V0RWxlbWVudFdpdGhSYW5kb21IcmVmKGVsZW1lbnQpIHtcblx0XHRlbGVtZW50LmhyZWYgPSBlbGVtZW50LmhyZWYgKyAnP3E9JyArIE1hdGgucmFuZG9tKCk7XG5cdFx0cmV0dXJuIGVsZW1lbnQ7XG5cdH1cblxuXHQvKipcblx0ICogT3ZlcnJpZGVzIGRvY3VtZW50IHJlZmVycmVyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSByZWZlcnJlclxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgc2V0UmVmZXJyZXIocmVmZXJyZXIpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFscy5kb2N1bWVudCwgJ3JlZmVycmVyJywge1xuXHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIHJlZmVycmVyO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHV0aWxzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG5cdGJhc2VQYXRoOiAnZGF0YS1zZW5uYS1iYXNlLXBhdGgnLFxuXHRsaW5rU2VsZWN0b3I6ICdkYXRhLXNlbm5hLWxpbmstc2VsZWN0b3InLFxuXHRsb2FkaW5nQ3NzQ2xhc3M6ICdkYXRhLXNlbm5hLWxvYWRpbmctY3NzLWNsYXNzJyxcblx0c2VubmE6ICdkYXRhLXNlbm5hJyxcblx0ZGlzcGF0Y2g6ICdkYXRhLXNlbm5hLWRpc3BhdGNoJyxcblx0c3VyZmFjZTogJ2RhdGEtc2VubmEtc3VyZmFjZScsXG5cdHVwZGF0ZVNjcm9sbFBvc2l0aW9uOiAnZGF0YS1zZW5uYS11cGRhdGUtc2Nyb2xsLXBvc2l0aW9uJ1xufTsiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlIHV0aWxpdHkuIEhvbGRzIGluZm9ybWF0aW9uIGFib3V0IGFuIGV2ZW50IHN1YnNjcmlwdGlvbiwgYW5kXG4gKiBhbGxvd3MgcmVtb3ZpbmcgdGhlbSBlYXNpbHkuXG4gKiBFdmVudEhhbmRsZSBpcyBhIERpc3Bvc2FibGUsIGJ1dCBpdCdzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhlXG4gKiBFdmVudEVtaXR0ZXIgdGhhdCBjcmVhdGVkIGl0IGlzIG5vdCB0aGUgb25lIHJlc3BvbnNpYmxlIGZvciBkaXNwb3NpbmcgaXQuXG4gKiBUaGF0IHJlc3BvbnNpYmlsaXR5IGlzIGZvciB0aGUgY29kZSB0aGF0IGhvbGRzIGEgcmVmZXJlbmNlIHRvIGl0LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBFdmVudEhhbmRsZSBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IGVtaXR0ZXIgRW1pdHRlciB0aGUgZXZlbnQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdGhhdCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgRXZlbnRFbWl0dGVyIGluc3RhbmNlIHRoYXQgdGhlIGV2ZW50IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZW1pdHRlcl8gPSBlbWl0dGVyO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRoYXQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudF8gPSBldmVudDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0XHQgKiBAdHlwZSB7RnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubGlzdGVuZXJfID0gbGlzdGVuZXI7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0dGhpcy5lbWl0dGVyXyA9IG51bGw7XG5cdFx0dGhpcy5saXN0ZW5lcl8gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIHN1YnNjcmlwdGlvbiBmcm9tIHRoZSBlbWl0dGVyLlxuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0aWYgKCF0aGlzLmVtaXR0ZXJfLmlzRGlzcG9zZWQoKSkge1xuXHRcdFx0dGhpcy5lbWl0dGVyXy5yZW1vdmVMaXN0ZW5lcih0aGlzLmV2ZW50XywgdGhpcy5saXN0ZW5lcl8pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudEhhbmRsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcnJheSwgRGlzcG9zYWJsZSwgaXNGdW5jdGlvbiwgaXNTdHJpbmd9IGZyb20gJ21ldGFsJztcbmltcG9ydCBFdmVudEhhbmRsZSBmcm9tICcuL0V2ZW50SGFuZGxlJztcblxuY29uc3Qgc2luZ2xlQXJyYXlfID0gWzBdO1xuXG4vKipcbiAqIEV2ZW50RW1pdHRlciB1dGlsaXR5LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50RW1pdHRlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRFbWl0dGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgZXZlbnQgbGlzdGVuZXJzIHNjb3BlZCBieSBldmVudCB0eXBlLlxuXHRcdCAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAhQXJyYXk8IWZ1bmN0aW9uKCk+Pn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhhbmRsZXJzIHRoYXQgYXJlIHRyaWdnZXJlZCB3aGVuIGFuIGV2ZW50IGlzIGxpc3RlbmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtBcnJheX1cblx0XHQgKi9cblx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIENvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZCBiZSBzZW50XG5cdFx0ICogYXMgYSBwYXJhbSBvZiBsaXN0ZW5lcnMgd2hlbiBlbWl0dGluZyBldmVudHMuIElmIHNldCB0byB0cnVlLCB0aGUgZmFjYWRlXG5cdFx0ICogd2lsbCBiZSBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoZSBsaXN0ZW5lci5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zaG91bGRVc2VGYWNhZGVfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGhhbmRsZXIgdG8gZ2l2ZW4gaG9sZGVyIHZhcmlhYmxlLiBJZiB0aGUgaG9sZGVyIGRvZXNuJ3QgaGF2ZSBhXG5cdCAqIHZhbHVlIHlldCwgaXQgd2lsbCByZWNlaXZlIHRoZSBoYW5kbGVyIGRpcmVjdGx5LiBJZiB0aGUgaG9sZGVyIGlzIGFuIGFycmF5LFxuXHQgKiB0aGUgdmFsdWUgd2lsbCBqdXN0IGJlIGFkZGVkIHRvIGl0LiBPdGhlcndpc2UsIHRoZSBob2xkZXIgd2lsbCBiZSBzZXQgdG8gYVxuXHQgKiBuZXcgYXJyYXkgY29udGFpbmluZyBpdHMgcHJldmlvdXMgdmFsdWUgcGx1cyB0aGUgbmV3IGhhbmRsZXIuXG5cdCAqIEBwYXJhbSB7Kn0gaG9sZGVyXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl8T2JqZWN0fSBoYW5kbGVyXG5cdCAqIEByZXR1cm4geyp9IFRoZSBob2xkZXIncyBuZXcgdmFsdWUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGFkZEhhbmRsZXJfKGhvbGRlciwgaGFuZGxlcikge1xuXHRcdGlmICghaG9sZGVyKSB7XG5cdFx0XHRob2xkZXIgPSBoYW5kbGVyO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIUFycmF5LmlzQXJyYXkoaG9sZGVyKSkge1xuXHRcdFx0XHRob2xkZXIgPSBbaG9sZGVyXTtcblx0XHRcdH1cblx0XHRcdGhvbGRlci5wdXNoKGhhbmRsZXIpO1xuXHRcdH1cblx0XHRyZXR1cm4gaG9sZGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG5cdCAqL1xuXHRhZGRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcikge1xuXHRcdHRoaXMudmFsaWRhdGVMaXN0ZW5lcl8obGlzdGVuZXIpO1xuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50c1tpXSwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBFdmVudEhhbmRsZSh0aGlzLCBldmVudCwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIGEgc2luZ2xlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9uPX0gb3JpZ2luIFRoZSBvcmlnaW5hbCBmdW5jdGlvbiB0aGF0IHdhcyBhZGRlZCBhcyBhXG5cdCAqICAgbGlzdGVuZXIsIGlmIHRoZXJlIGlzIGFueS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lciwgZGVmYXVsdExpc3RlbmVyLCBvcmlnaW4pIHtcblx0XHR0aGlzLnJ1bkxpc3RlbmVySGFuZGxlcnNfKGV2ZW50KTtcblx0XHRpZiAoZGVmYXVsdExpc3RlbmVyIHx8IG9yaWdpbikge1xuXHRcdFx0bGlzdGVuZXIgPSB7XG5cdFx0XHRcdGRlZmF1bHQ6IGRlZmF1bHRMaXN0ZW5lcixcblx0XHRcdFx0Zm46IGxpc3RlbmVyLFxuXHRcdFx0XHRvcmlnaW46IG9yaWdpbixcblx0XHRcdH07XG5cdFx0fVxuXHRcdHRoaXMuZXZlbnRzXyA9IHRoaXMuZXZlbnRzXyB8fCB7fTtcblx0XHR0aGlzLmV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRIYW5kbGVyXyh0aGlzLmV2ZW50c19bZXZlbnRdLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGZhY2FkZSBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7T2JqZWN0fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRidWlsZEZhY2FkZV8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy5nZXRTaG91bGRVc2VGYWNhZGUoKSkge1xuXHRcdFx0Y29uc3QgZmFjYWRlID0ge1xuXHRcdFx0XHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0ZmFjYWRlLnByZXZlbnRlZERlZmF1bHQgPSB0cnVlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0YXJnZXQ6IHRoaXMsXG5cdFx0XHRcdHR5cGU6IGV2ZW50LFxuXHRcdFx0fTtcblx0XHRcdHJldHVybiBmYWNhZGU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeGVjdXRlIGVhY2ggb2YgdGhlIGxpc3RlbmVycyBpbiBvcmRlciB3aXRoIHRoZSBzdXBwbGllZCBhcmd1bWVudHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyp9IG9wdF9hcmdzIFthcmcxXSwgW2FyZzJdLCBbLi4uXVxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgZXZlbnQgaGFkIGxpc3RlbmVycywgZmFsc2Ugb3RoZXJ3aXNlLlxuXHQgKi9cblx0ZW1pdChldmVudCkge1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCk7XG5cdFx0aWYgKGxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRjb25zdCBhcmdzID0gYXJyYXkuc2xpY2UoYXJndW1lbnRzLCAxKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdHRoaXMucnVuTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGFyZ3MsIHRoaXMuYnVpbGRGYWNhZGVfKGV2ZW50KSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbGlzdGVuZXIgb2JqZWN0cyBmb3IgdGhlIGdpdmVuIGV2ZW50LCBpZiB0aGVyZSBhcmUgYW55LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRnZXRSYXdMaXN0ZW5lcnNfKGV2ZW50KSB7XG5cdFx0Y29uc3QgZGlyZWN0TGlzdGVuZXJzID0gdG9BcnJheSh0aGlzLmV2ZW50c18gJiYgdGhpcy5ldmVudHNfW2V2ZW50XSk7XG5cdFx0cmV0dXJuIGRpcmVjdExpc3RlbmVycy5jb25jYXQoXG5cdFx0XHR0b0FycmF5KHRoaXMuZXZlbnRzXyAmJiB0aGlzLmV2ZW50c19bJyonXSlcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Z2V0U2hvdWxkVXNlRmFjYWRlKCkge1xuXHRcdHJldHVybiB0aGlzLnNob3VsZFVzZUZhY2FkZV87XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgbGlzdGVuZXJzLlxuXHQgKi9cblx0bGlzdGVuZXJzKGV2ZW50KSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCkubWFwKFxuXHRcdFx0bGlzdGVuZXIgPT4gKGxpc3RlbmVyLmZuID8gbGlzdGVuZXIuZm4gOiBsaXN0ZW5lcilcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIGZpeGVkIG51bWJlciBvZiB0aW1lcyBmb3IgdGhlXG5cdCAqIGV2ZW50cy4gQWZ0ZXIgZWFjaCBldmVudCBpcyB0cmlnZ2VyZWQgdGhlIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZXMsIHRoZVxuXHQgKiBsaXN0ZW5lciBpcyByZW1vdmVkIGZvciBpdC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cblx0ICovXG5cdG1hbnkoZXZlbnQsIGFtb3VudCwgbGlzdGVuZXIpIHtcblx0XHRjb25zdCBldmVudHMgPSB0aGlzLnRvRXZlbnRzQXJyYXlfKGV2ZW50KTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5tYW55XyhldmVudHNbaV0sIGFtb3VudCwgbGlzdGVuZXIpO1xuXHRcdH1cblxuXHRcdHJldHVybiBuZXcgRXZlbnRIYW5kbGUodGhpcywgZXZlbnQsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgYSBmaXhlZCBudW1iZXIgb2YgdGltZXMgZm9yIGEgc2luZ2xlXG5cdCAqIGV2ZW50LiBBZnRlciB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWVzLCB0aGVcblx0ICogbGlzdGVuZXIgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG1hbnlfKGV2ZW50LCBhbW91bnQsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3Qgc2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoYW1vdW50IDw9IDApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKlxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGhhbmRsZXJJbnRlcm5hbCgpIHtcblx0XHRcdGlmICgtLWFtb3VudCA9PT0gMCkge1xuXHRcdFx0XHRzZWxmLnJlbW92ZUxpc3RlbmVyKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwpO1xuXHRcdFx0fVxuXHRcdFx0bGlzdGVuZXIuYXBwbHkoc2VsZiwgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdH1cblxuXHRcdHNlbGYuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwsIGZhbHNlLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGEgbGlzdGVuZXIgb2JqZWN0IG1hdGNoZXMgdGhlIGdpdmVuIGxpc3RlbmVyIGZ1bmN0aW9uLiBUbyBtYXRjaCxcblx0ICogaXQgbmVlZHMgdG8gZWl0aGVyIHBvaW50IHRvIHRoYXQgbGlzdGVuZXIgb3IgaGF2ZSBpdCBhcyBpdHMgb3JpZ2luLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGxpc3RlbmVyT2JqXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXRjaGVzTGlzdGVuZXJfKGxpc3RlbmVyT2JqLCBsaXN0ZW5lcikge1xuXHRcdGNvbnN0IGZuID0gbGlzdGVuZXJPYmouZm4gfHwgbGlzdGVuZXJPYmo7XG5cdFx0cmV0dXJuIChcblx0XHRcdGZuID09PSBsaXN0ZW5lciB8fFxuXHRcdFx0KGxpc3RlbmVyT2JqLm9yaWdpbiAmJiBsaXN0ZW5lck9iai5vcmlnaW4gPT09IGxpc3RlbmVyKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudFxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IU9iamVjdH0gUmV0dXJucyBlbWl0dGVyLCBzbyBjYWxscyBjYW4gYmUgY2hhaW5lZC5cblx0ICovXG5cdG9mZihldmVudCwgbGlzdGVuZXIpIHtcblx0XHR0aGlzLnZhbGlkYXRlTGlzdGVuZXJfKGxpc3RlbmVyKTtcblx0XHRpZiAoIXRoaXMuZXZlbnRzXykge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRzX1tldmVudHNbaV1dID0gdGhpcy5yZW1vdmVNYXRjaGluZ0xpc3RlbmVyT2Jqc18oXG5cdFx0XHRcdHRvQXJyYXkodGhpcy5ldmVudHNfW2V2ZW50c1tpXV0pLFxuXHRcdFx0XHRsaXN0ZW5lclxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50cy5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgaGFuZGxlciB0aGF0IGdldHMgdHJpZ2dlcmVkIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8gb24gdGhpc1xuXHQgKiBpbnN0YW5jZS5cblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gaGFuZGxlclxuXHQgKi9cblx0b25MaXN0ZW5lcihoYW5kbGVyKSB7XG5cdFx0dGhpcy5saXN0ZW5lckhhbmRsZXJzXyA9IHRoaXMuYWRkSGFuZGxlcl8oXG5cdFx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfLFxuXHRcdFx0aGFuZGxlclxuXHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudHMuIFRoaXMgbGlzdGVuZXIgaXMgaW52b2tlZCBvbmx5IHRoZVxuXHQgKiBuZXh0IHRpbWUgZWFjaCBldmVudCBpcyBmaXJlZCwgYWZ0ZXIgd2hpY2ggaXQgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b25jZShldmVudHMsIGxpc3RlbmVyKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFueShldmVudHMsIDEsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnRzLiBJdCdzIG5vdCBhIGdvb2Rcblx0ICogaWRlYSB0byByZW1vdmUgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZCBlbHNld2hlcmUgaW4gdGhlIGNvZGUsXG5cdCAqIGVzcGVjaWFsbHkgd2hlbiBpdCdzIG9uIGFuIGVtaXR0ZXIgdGhhdCB5b3UgZGlkbid0IGNyZWF0ZS5cblx0ICogQHBhcmFtIHsoQXJyYXl8c3RyaW5nKT19IGV2ZW50XG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnQpIHtcblx0XHRpZiAodGhpcy5ldmVudHNfKSB7XG5cdFx0XHRpZiAoZXZlbnQpIHtcblx0XHRcdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5ldmVudHNfW2V2ZW50c1tpXV0gPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmV2ZW50c18gPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lciBvYmplY3RzIGZyb20gdGhlIGdpdmVuIGFycmF5IHRoYXQgbWF0Y2ggdGhlIGdpdmVuXG5cdCAqIGxpc3RlbmVyIGZ1bmN0aW9uLlxuXHQgKiBAcGFyYW0ge0FycmF5LjxPYmplY3Q+fSBsaXN0ZW5lck9ianNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4ge0FycmF5LjxPYmplY3Q+fE9iamVjdH0gVGhlIG5ldyBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoaXMgZXZlbnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZU1hdGNoaW5nTGlzdGVuZXJPYmpzXyhsaXN0ZW5lck9ianMsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3QgZmluYWxMaXN0ZW5lcnMgPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVyT2Jqcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKCF0aGlzLm1hdGNoZXNMaXN0ZW5lcl8obGlzdGVuZXJPYmpzW2ldLCBsaXN0ZW5lcikpIHtcblx0XHRcdFx0ZmluYWxMaXN0ZW5lcnMucHVzaChsaXN0ZW5lck9ianNbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmluYWxMaXN0ZW5lcnMubGVuZ3RoID4gMCA/IGZpbmFsTGlzdGVuZXJzIDogbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGhhbmRsZXJzIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRydW5MaXN0ZW5lckhhbmRsZXJzXyhldmVudCkge1xuXHRcdGxldCBoYW5kbGVycyA9IHRoaXMubGlzdGVuZXJIYW5kbGVyc187XG5cdFx0aWYgKGhhbmRsZXJzKSB7XG5cdFx0XHRoYW5kbGVycyA9IHRvQXJyYXkoaGFuZGxlcnMpO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBoYW5kbGVycy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRoYW5kbGVyc1tpXShldmVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGdpdmVuIGxpc3RlbmVycy5cblx0ICogQHBhcmFtIHshQXJyYXl9IGxpc3RlbmVyc1xuXHQgKiBAcGFyYW0geyFBcnJheX0gYXJnc1xuXHQgKiBAcGFyYW0ge09iamVjdH0gZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJ1bkxpc3RlbmVyc18obGlzdGVuZXJzLCBhcmdzLCBmYWNhZGUpIHtcblx0XHRpZiAoZmFjYWRlKSB7XG5cdFx0XHRhcmdzLnB1c2goZmFjYWRlKTtcblx0XHR9XG5cblx0XHRjb25zdCBkZWZhdWx0TGlzdGVuZXJzID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldLmZuIHx8IGxpc3RlbmVyc1tpXTtcblx0XHRcdGlmIChsaXN0ZW5lcnNbaV0uZGVmYXVsdCkge1xuXHRcdFx0XHRkZWZhdWx0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICghZmFjYWRlIHx8ICFmYWNhZGUucHJldmVudGVkRGVmYXVsdCkge1xuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBkZWZhdWx0TGlzdGVuZXJzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdGRlZmF1bHRMaXN0ZW5lcnNbal0uYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFVzZUZhY2FkZVxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fSBSZXR1cm5zIGVtaXR0ZXIsIHNvIGNhbGxzIGNhbiBiZSBjaGFpbmVkLlxuXHQgKi9cblx0c2V0U2hvdWxkVXNlRmFjYWRlKHNob3VsZFVzZUZhY2FkZSkge1xuXHRcdHRoaXMuc2hvdWxkVXNlRmFjYWRlXyA9IHNob3VsZFVzZUZhY2FkZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyB0aGUgcGFyYW1ldGVyIHRvIGFuIGFycmF5IGlmIG9ubHkgb25lIGV2ZW50IGlzIGdpdmVuLiBSZXVzZXMgdGhlXG5cdCAqIHNhbWUgYXJyYXkgZWFjaCB0aW1lIHRoaXMgY29udmVyc2lvbiBpcyBkb25lLCB0byBhdm9pZCB1c2luZyBtb3JlIG1lbW9yeVxuXHQgKiB0aGFuIG5lY2Vzc2FyeS5cblx0ICogQHBhcmFtICB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0b0V2ZW50c0FycmF5XyhldmVudHMpIHtcblx0XHRpZiAoaXNTdHJpbmcoZXZlbnRzKSkge1xuXHRcdFx0c2luZ2xlQXJyYXlfWzBdID0gZXZlbnRzO1xuXHRcdFx0ZXZlbnRzID0gc2luZ2xlQXJyYXlfO1xuXHRcdH1cblx0XHRyZXR1cm4gZXZlbnRzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbGlzdGVuZXIgaXMgdmFsaWQsIHRocm93aW5nIGFuIGV4Y2VwdGlvbiB3aGVuIGl0J3Mgbm90LlxuXHQgKiBAcGFyYW0gIHsqfSBsaXN0ZW5lclxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR2YWxpZGF0ZUxpc3RlbmVyXyhsaXN0ZW5lcikge1xuXHRcdGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIENvbnZlcnRzIHRvIGFuIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gdmFsXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdG9BcnJheSh2YWwpIHtcblx0dmFsID0gdmFsIHx8IFtdO1xuXHRyZXR1cm4gQXJyYXkuaXNBcnJheSh2YWwpID8gdmFsIDogW3ZhbF07XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50RW1pdHRlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtEaXNwb3NhYmxlfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogRXZlbnRFbWl0dGVyUHJveHkgdXRpbGl0eS4gSXQncyByZXNwb25zaWJsZSBmb3IgbGlua2luZyB0d28gRXZlbnRFbWl0dGVyXG4gKiBpbnN0YW5jZXMgdG9nZXRoZXIsIGVtaXR0aW5nIGV2ZW50cyBmcm9tIHRoZSBmaXJzdCBlbWl0dGVyIHRocm91Z2ggdGhlXG4gKiBzZWNvbmQgb25lLiBUaGF0IG1lYW5zIHRoYXQgbGlzdGVuaW5nIHRvIGEgc3VwcG9ydGVkIGV2ZW50IG9uIHRoZSB0YXJnZXRcbiAqIGVtaXR0ZXIgd2lsbCBtZWFuIGxpc3RlbmluZyB0byBpdCBvbiB0aGUgb3JpZ2luIGVtaXR0ZXIgYXMgd2VsbC5cbiAqIEBleHRlbmRzIHtEaXNwb3NhYmxlfVxuICovXG5jbGFzcyBFdmVudEVtaXR0ZXJQcm94eSBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXIgRXZlbnRzIG9yaWdpbmF0ZWQgb24gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYmUgZmlyZWQgZm9yIHRoZSB0YXJnZXQgZW1pdHRlcidzIGxpc3RlbmVycyBhcyB3ZWxsLlxuXHQgKiBAcGFyYW0ge0V2ZW50RW1pdHRlcn0gdGFyZ2V0RW1pdHRlciBFdmVudCBsaXN0ZW5lcnMgYXR0YWNoZWQgdG8gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYWxzbyBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgZXZlbnQgaXMgZmlyZWQgYnkgdGhlIG9yaWdpbiBlbWl0dGVyLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gYmxhY2tsaXN0IE9wdGlvbmFsIGJsYWNrbGlzdCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlXG5cdCAqIHByb3hpZWQuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB3aGl0ZWxpc3Rcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9yaWdpbkVtaXR0ZXIsIHRhcmdldEVtaXR0ZXIsIGJsYWNrbGlzdCwgd2hpdGVsaXN0KSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ibGFja2xpc3RfID0gYmxhY2tsaXN0O1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG9yaWdpbiBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIncyBldmVudHMgd2lsbCBiZSBwcm94aWVkIHRocm91Z2ggdGhlXG5cdFx0ICogdGFyZ2V0IGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBBIGxpc3Qgb2YgZXZlbnRzIHRoYXQgYXJlIHBlbmRpbmcgdG8gYmUgbGlzdGVuZWQgYnkgYW4gYWN0dWFsIG9yaWdpblxuXHRcdCAqIGVtaXR0ZXIuIEV2ZW50cyBhcmUgc3RvcmVkIGhlcmUgd2hlbiB0aGUgb3JpZ2luIGRvZXNuJ3QgZXhpc3QsIHNvIHRoZXlcblx0XHQgKiBjYW4gYmUgc2V0IG9uIGEgbmV3IG9yaWdpbiB3aGVuIG9uZSBpcyBzZXQuXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBlbmRpbmdFdmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGEgbWFwIG9mIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gZW1pdHRlciB0aGF0IGFyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdDxzdHJpbmcsICFFdmVudEhhbmRsZT59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucHJveGllZEV2ZW50c18gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIHRhcmdldCBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIgd2lsbCBlbWl0IGFsbCBldmVudHMgdGhhdCBjb21lIGZyb21cblx0XHQgKiB0aGUgb3JpZ2luIGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy50YXJnZXRFbWl0dGVyXyA9IHRhcmdldEVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBNYXAgb2YgZXZlbnRzIHRoYXQgc2hvdWxkIGJlIHByb3hpZWQuIElmIHdoaXRlbGlzdCBpcyBzZXQgYmxhY2tsaXN0IGlzIGlnbm9yZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy53aGl0ZWxpc3RfID0gd2hpdGVsaXN0O1xuXG5cdFx0dGhpcy5zdGFydFByb3h5XygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIGdpdmVuIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IFRoZSBsaXN0ZW5lZCBldmVudCdzIGhhbmRsZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHJldHVybiB0aGlzLm9yaWdpbkVtaXR0ZXJfLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyc18oKTtcblx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfID0gbnVsbDtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbWl0cyB0aGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUgb24gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRlbWl0T25UYXJnZXRfKC4uLmFyZ3MpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLmVtaXQoLi4uYXJncyk7XG5cdH1cblxuXHQvKipcblx0ICogUHJveGllcyB0aGUgZ2l2ZW4gZXZlbnQgZnJvbSB0aGUgb3JpZ2luIHRvIHRoZSB0YXJnZXQgZW1pdHRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqL1xuXHRwcm94eUV2ZW50KGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuc2hvdWxkUHJveHlFdmVudF8oZXZlbnQpKSB7XG5cdFx0XHR0aGlzLnRyeVRvQWRkTGlzdGVuZXJfKGV2ZW50KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgcHJveHkgbGlzdGVuZXIgZm9yIGFsbCBldmVudHMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZUxpc3RlbmVyc18oKSB7XG5cdFx0aWYgKHRoaXMucHJveGllZEV2ZW50c18pIHtcblx0XHRcdGNvbnN0IGV2ZW50cyA9IE9iamVjdC5rZXlzKHRoaXMucHJveGllZEV2ZW50c18pO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0dGhpcy5wcm94aWVkRXZlbnRzX1tldmVudHNbaV1dLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR9XG5cdFx0dGhpcy5wZW5kaW5nRXZlbnRzXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQ2hhbmdlcyB0aGUgb3JpZ2luIGVtaXR0ZXIuIFRoaXMgYXV0b21hdGljYWxseSBkZXRhY2hlcyBhbnkgZXZlbnRzIHRoYXRcblx0ICogd2VyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQgZnJvbSB0aGUgcHJldmlvdXMgZW1pdHRlciwgYW5kIHN0YXJ0cyBwcm94eWluZ1xuXHQgKiB0aGVtIG9uIHRoZSBuZXcgZW1pdHRlciBpbnN0ZWFkLlxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXJcblx0ICovXG5cdHNldE9yaWdpbkVtaXR0ZXIob3JpZ2luRW1pdHRlcikge1xuXHRcdGNvbnN0IGV2ZW50cyA9XG5cdFx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfICYmIHRoaXMucHJveGllZEV2ZW50c19cblx0XHRcdFx0PyBPYmplY3Qua2V5cyh0aGlzLnByb3hpZWRFdmVudHNfKVxuXHRcdFx0XHQ6IHRoaXMucGVuZGluZ0V2ZW50c187XG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cdFx0aWYgKGV2ZW50cykge1xuXHRcdFx0dGhpcy5yZW1vdmVMaXN0ZW5lcnNfKCk7XG5cdFx0XHRldmVudHMuZm9yRWFjaChldmVudCA9PiB0aGlzLnByb3h5RXZlbnQoZXZlbnQpKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBzaG91bGQgYmUgcHJveGllZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHNob3VsZFByb3h5RXZlbnRfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMud2hpdGVsaXN0XyAmJiAhdGhpcy53aGl0ZWxpc3RfW2V2ZW50XSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAodGhpcy5ibGFja2xpc3RfICYmIHRoaXMuYmxhY2tsaXN0X1tldmVudF0pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuICF0aGlzLnByb3hpZWRFdmVudHNfIHx8ICF0aGlzLnByb3hpZWRFdmVudHNfW2V2ZW50XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgcHJveHlpbmcgYWxsIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gdG8gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzdGFydFByb3h5XygpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLm9uTGlzdGVuZXIodGhpcy5wcm94eUV2ZW50LmJpbmQodGhpcykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgb3JpZ2luIGVtaXR0ZXIsIGlmIGl0IGV4aXN0cy4gT3RoZXJ3aXNlLCBzdG9yZXNcblx0ICogdGhlIHBlbmRpbmcgbGlzdGVuZXIgc28gaXQgY2FuIGJlIHVzZWQgb24gYSBmdXR1cmUgb3JpZ2luIGVtaXR0ZXIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0cnlUb0FkZExpc3RlbmVyXyhldmVudCkge1xuXHRcdGlmICh0aGlzLm9yaWdpbkVtaXR0ZXJfKSB7XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gdGhpcy5wcm94aWVkRXZlbnRzXyB8fCB7fTtcblx0XHRcdHRoaXMucHJveGllZEV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRMaXN0ZW5lcl8oXG5cdFx0XHRcdGV2ZW50LFxuXHRcdFx0XHR0aGlzLmVtaXRPblRhcmdldF8uYmluZCh0aGlzLCBldmVudClcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucGVuZGluZ0V2ZW50c18gPSB0aGlzLnBlbmRpbmdFdmVudHNfIHx8IFtdO1xuXHRcdFx0dGhpcy5wZW5kaW5nRXZlbnRzXy5wdXNoKGV2ZW50KTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRFbWl0dGVyUHJveHk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlciB1dGlsaXR5LiBJdCdzIHVzZWZ1bCBmb3IgZWFzaWx5IHJlbW92aW5nIGEgZ3JvdXAgb2ZcbiAqIGxpc3RlbmVycyBmcm9tIGRpZmZlcmVudCBFdmVudEVtaXR0ZXIgaW5zdGFuY2VzLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRIYW5kbGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogQW4gYXJyYXkgdGhhdCBob2xkcyB0aGUgYWRkZWQgZXZlbnQgaGFuZGxlcywgc28gdGhlIGxpc3RlbmVycyBjYW4gYmVcblx0XHQgKiByZW1vdmVkIGxhdGVyLlxuXHRcdCAqIEB0eXBlIHtBcnJheS48RXZlbnRIYW5kbGU+fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGV2ZW50IGhhbmRsZXMgdG8gYmUgcmVtb3ZlZCBsYXRlciB0aHJvdWdoIHRoZSBgcmVtb3ZlQWxsTGlzdGVuZXJzYFxuXHQgKiBtZXRob2QuXG5cdCAqIEBwYXJhbSB7Li4uKCFFdmVudEhhbmRsZSl9IHZhcl9hcmdzXG5cdCAqL1xuXHRhZGQoLi4uYXJncykge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmV2ZW50SGFuZGxlc18ucHVzaChhcmdzW2ldKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyB0aGF0IGhhdmUgYmVlbiBhZGRlZCB0aHJvdWdoIHRoZSBgYWRkYCBtZXRob2QuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmV2ZW50SGFuZGxlc18ubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRIYW5kbGVzX1tpXS5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdH1cblxuXHRcdHRoaXMuZXZlbnRIYW5kbGVzXyA9IFtdO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50SGFuZGxlcjtcbiIsIi8qIVxuICogUHJvbWlzZXMgcG9seWZpbGwgZnJvbSBHb29nbGUncyBDbG9zdXJlIExpYnJhcnkuXG4gKlxuICogICAgICBDb3B5cmlnaHQgMjAxMyBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTk9URShlZHVhcmRvKTogUHJvbWlzZSBzdXBwb3J0IGlzIG5vdCByZWFkeSBvbiBhbGwgc3VwcG9ydGVkIGJyb3dzZXJzLFxuICogdGhlcmVmb3JlIG1ldGFsLXByb21pc2UgaXMgdGVtcG9yYXJpbHkgdXNpbmcgR29vZ2xlJ3MgcHJvbWlzZXMgYXMgcG9seWZpbGwuXG4gKiBJdCBzdXBwb3J0cyBjYW5jZWxsYWJsZSBwcm9taXNlcyBhbmQgaGFzIGNsZWFuIGFuZCBmYXN0IGltcGxlbWVudGF0aW9uLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgaXNEZWYsIGlzRnVuY3Rpb24sIGlzT2JqZWN0IH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgYXN5bmMgfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogUHJvdmlkZXMgYSBtb3JlIHN0cmljdCBpbnRlcmZhY2UgZm9yIFRoZW5hYmxlcyBpbiB0ZXJtcyBvZlxuICogaHR0cDovL3Byb21pc2VzYXBsdXMuY29tIGZvciBpbnRlcm9wIHdpdGgge0BzZWUgQ2FuY2VsbGFibGVQcm9taXNlfS5cbiAqXG4gKiBAaW50ZXJmYWNlXG4gKiBAZXh0ZW5kcyB7SVRoZW5hYmxlLjxUWVBFPn1cbiAqIEB0ZW1wbGF0ZSBUWVBFXG4gKi9cbnZhciBUaGVuYWJsZSA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogQWRkcyBjYWxsYmFja3MgdGhhdCB3aWxsIG9wZXJhdGUgb24gdGhlIHJlc3VsdCBvZiB0aGUgVGhlbmFibGUsIHJldHVybmluZyBhXG4gKiBuZXcgY2hpbGQgUHJvbWlzZS5cbiAqXG4gKiBJZiB0aGUgVGhlbmFibGUgaXMgZnVsZmlsbGVkLCB0aGUge0Bjb2RlIG9uRnVsZmlsbGVkfSBjYWxsYmFjayB3aWxsIGJlXG4gKiBpbnZva2VkIHdpdGggdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGFzIGFyZ3VtZW50LCBhbmQgdGhlIGNoaWxkIFByb21pc2Ugd2lsbFxuICogYmUgZnVsZmlsbGVkIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgY2FsbGJhY2suIElmIHRoZSBjYWxsYmFjayB0aHJvd3NcbiAqIGFuIGV4Y2VwdGlvbiwgdGhlIGNoaWxkIFByb21pc2Ugd2lsbCBiZSByZWplY3RlZCB3aXRoIHRoZSB0aHJvd24gdmFsdWVcbiAqIGluc3RlYWQuXG4gKlxuICogSWYgdGhlIFRoZW5hYmxlIGlzIHJlamVjdGVkLCB0aGUge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZFxuICogd2l0aCB0aGUgcmVqZWN0aW9uIHJlYXNvbiBhcyBhcmd1bWVudCwgYW5kIHRoZSBjaGlsZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWRcbiAqIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgY2FsbGJhY2sgb3IgdGhyb3duIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7PyhmdW5jdGlvbih0aGlzOlRISVMsIFRZUEUpOlxuICogICAgICAgICAgICAgKFJFU1VMVHxJVGhlbmFibGUuPFJFU1VMVD58VGhlbmFibGUpKT19IG9wdF9vbkZ1bGZpbGxlZCBBXG4gKiAgICAgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGludm9rZWQgd2l0aCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgaWYgdGhlIFByb21pc2VcbiAqICAgICBpcyBmdWxsZmlsbGVkLlxuICogQHBhcmFtIHs/KGZ1bmN0aW9uKCopOiAqKT19IG9wdF9vblJlamVjdGVkIEEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGludm9rZWRcbiAqICAgICB3aXRoIHRoZSByZWplY3Rpb24gcmVhc29uIGlmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLlxuICogQHBhcmFtIHtUSElTPX0gb3B0X2NvbnRleHQgQW4gb3B0aW9uYWwgY29udGV4dCBvYmplY3QgdGhhdCB3aWxsIGJlIHRoZVxuICogICAgIGV4ZWN1dGlvbiBjb250ZXh0IGZvciB0aGUgY2FsbGJhY2tzLiBCeSBkZWZhdWx0LCBmdW5jdGlvbnMgYXJlIGV4ZWN1dGVkXG4gKiAgICAgd2l0aCB0aGUgZGVmYXVsdCB0aGlzLlxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48UkVTVUxUPn0gQSBuZXcgUHJvbWlzZSB0aGF0IHdpbGwgcmVjZWl2ZSB0aGVcbiAqICAgICByZXN1bHQgb2YgdGhlIGZ1bGZpbGxtZW50IG9yIHJlamVjdGlvbiBjYWxsYmFjay5cbiAqIEB0ZW1wbGF0ZSBSRVNVTFQsVEhJU1xuICovXG5UaGVuYWJsZS5wcm90b3R5cGUudGhlbiA9IGZ1bmN0aW9uKCkge307XG5cblxuLyoqXG4gKiBBbiBleHBhbmRvIHByb3BlcnR5IHRvIGluZGljYXRlIHRoYXQgYW4gb2JqZWN0IGltcGxlbWVudHNcbiAqIHtAY29kZSBUaGVuYWJsZX0uXG4gKlxuICoge0BzZWUgYWRkSW1wbGVtZW50YXRpb259LlxuICpcbiAqIEBjb25zdFxuICovXG5UaGVuYWJsZS5JTVBMRU1FTlRFRF9CWV9QUk9QID0gJyRnb29nX1RoZW5hYmxlJztcblxuXG4vKipcbiAqIE1hcmtzIGEgZ2l2ZW4gY2xhc3MgKGNvbnN0cnVjdG9yKSBhcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBUaGVuYWJsZSwgc29cbiAqIHRoYXQgd2UgY2FuIHF1ZXJ5IHRoYXQgZmFjdCBhdCBydW50aW1lLiBUaGUgY2xhc3MgbXVzdCBoYXZlIGFscmVhZHlcbiAqIGltcGxlbWVudGVkIHRoZSBpbnRlcmZhY2UuXG4gKiBFeHBvcnRzIGEgJ3RoZW4nIG1ldGhvZCBvbiB0aGUgY29uc3RydWN0b3IgcHJvdG90eXBlLCBzbyB0aGF0IHRoZSBvYmplY3RzXG4gKiBhbHNvIGltcGxlbWVudCB0aGUgZXh0ZXJuIHtAc2VlIFRoZW5hYmxlfSBpbnRlcmZhY2UgZm9yIGludGVyb3Agd2l0aFxuICogb3RoZXIgUHJvbWlzZSBpbXBsZW1lbnRhdGlvbnMuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG5ldzpUaGVuYWJsZSwuLi5bP10pfSBjdG9yIFRoZSBjbGFzcyBjb25zdHJ1Y3Rvci4gVGhlXG4gKiAgICAgY29ycmVzcG9uZGluZyBjbGFzcyBtdXN0IGhhdmUgYWxyZWFkeSBpbXBsZW1lbnRlZCB0aGUgaW50ZXJmYWNlLlxuICovXG5UaGVuYWJsZS5hZGRJbXBsZW1lbnRhdGlvbiA9IGZ1bmN0aW9uKGN0b3IpIHtcbiAgY3Rvci5wcm90b3R5cGUudGhlbiA9IGN0b3IucHJvdG90eXBlLnRoZW47XG4gIGN0b3IucHJvdG90eXBlLiRnb29nX1RoZW5hYmxlID0gdHJ1ZTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0geyp9IG9iamVjdFxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciBhIGdpdmVuIGluc3RhbmNlIGltcGxlbWVudHMge0Bjb2RlIFRoZW5hYmxlfS5cbiAqICAgICBUaGUgY2xhc3Mvc3VwZXJjbGFzcyBvZiB0aGUgaW5zdGFuY2UgbXVzdCBjYWxsIHtAY29kZSBhZGRJbXBsZW1lbnRhdGlvbn0uXG4gKi9cblRoZW5hYmxlLmlzSW1wbGVtZW50ZWRCeSA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICBpZiAoIW9iamVjdCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiAhIW9iamVjdC4kZ29vZ19UaGVuYWJsZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIFByb3BlcnR5IGFjY2VzcyBzZWVtcyB0byBiZSBmb3JiaWRkZW4uXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5cbi8qKlxuICogTGlrZSBiaW5kKCksIGV4Y2VwdCB0aGF0IGEgJ3RoaXMgb2JqZWN0JyBpcyBub3QgcmVxdWlyZWQuIFVzZWZ1bCB3aGVuIHRoZVxuICogdGFyZ2V0IGZ1bmN0aW9uIGlzIGFscmVhZHkgYm91bmQuXG4gKlxuICogVXNhZ2U6XG4gKiB2YXIgZyA9IHBhcnRpYWwoZiwgYXJnMSwgYXJnMik7XG4gKiBnKGFyZzMsIGFyZzQpO1xuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIEEgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5LlxuICogQHBhcmFtIHsuLi4qfSB2YXJfYXJncyBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0aGF0IGFyZSBwYXJ0aWFsbHkgYXBwbGllZCB0byBmbi5cbiAqIEByZXR1cm4geyFGdW5jdGlvbn0gQSBwYXJ0aWFsbHktYXBwbGllZCBmb3JtIG9mIHRoZSBmdW5jdGlvbiBiaW5kKCkgd2FzXG4gKiAgICAgaW52b2tlZCBhcyBhIG1ldGhvZCBvZi5cbiAqL1xudmFyIHBhcnRpYWwgPSBmdW5jdGlvbihmbikge1xuICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAvLyBDbG9uZSB0aGUgYXJyYXkgKHdpdGggc2xpY2UoKSkgYW5kIGFwcGVuZCBhZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgIC8vIHRvIHRoZSBleGlzdGluZyBhcmd1bWVudHMuXG4gICAgdmFyIG5ld0FyZ3MgPSBhcmdzLnNsaWNlKCk7XG4gICAgbmV3QXJncy5wdXNoLmFwcGx5KG5ld0FyZ3MsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIG5ld0FyZ3MpO1xuICB9O1xufTtcblxuLyoqXG4gKiBQcm9taXNlcyBwcm92aWRlIGEgcmVzdWx0IHRoYXQgbWF5IGJlIHJlc29sdmVkIGFzeW5jaHJvbm91c2x5LiBBIFByb21pc2UgbWF5XG4gKiBiZSByZXNvbHZlZCBieSBiZWluZyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQgd2l0aCBhIHZhbHVlLCB3aGljaCB3aWxsIGJlIGtub3duXG4gKiBhcyB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgb3IgdGhlIHJlamVjdGlvbiByZWFzb24uIFdoZXRoZXIgZnVsZmlsbGVkIG9yXG4gKiByZWplY3RlZCwgdGhlIFByb21pc2UgcmVzdWx0IGlzIGltbXV0YWJsZSBvbmNlIGl0IGlzIHNldC5cbiAqXG4gKiBQcm9taXNlcyBtYXkgcmVwcmVzZW50IHJlc3VsdHMgb2YgYW55IHR5cGUsIGluY2x1ZGluZyB1bmRlZmluZWQuIFJlamVjdGlvblxuICogcmVhc29ucyBhcmUgdHlwaWNhbGx5IEVycm9ycywgYnV0IG1heSBhbHNvIGJlIG9mIGFueSB0eXBlLiBDbG9zdXJlIFByb21pc2VzXG4gKiBhbGxvdyBmb3Igb3B0aW9uYWwgdHlwZSBhbm5vdGF0aW9ucyB0aGF0IGVuZm9yY2UgdGhhdCBmdWxmaWxsbWVudCB2YWx1ZXMgYXJlXG4gKiBvZiB0aGUgYXBwcm9wcmlhdGUgdHlwZXMgYXQgY29tcGlsZSB0aW1lLlxuICpcbiAqIFRoZSByZXN1bHQgb2YgYSBQcm9taXNlIGlzIGFjY2Vzc2libGUgYnkgY2FsbGluZyB7QGNvZGUgdGhlbn0gYW5kIHJlZ2lzdGVyaW5nXG4gKiB7QGNvZGUgb25GdWxmaWxsZWR9IGFuZCB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tzLiBPbmNlIHRoZSBQcm9taXNlXG4gKiByZXNvbHZlcywgdGhlIHJlbGV2YW50IGNhbGxiYWNrcyBhcmUgaW52b2tlZCB3aXRoIHRoZSBmdWxmaWxsbWVudCB2YWx1ZSBvclxuICogcmVqZWN0aW9uIHJlYXNvbiBhcyBhcmd1bWVudC4gQ2FsbGJhY2tzIGFyZSBhbHdheXMgaW52b2tlZCBpbiB0aGUgb3JkZXIgdGhleVxuICogd2VyZSByZWdpc3RlcmVkLCBldmVuIHdoZW4gYWRkaXRpb25hbCB7QGNvZGUgdGhlbn0gY2FsbHMgYXJlIG1hZGUgZnJvbSBpbnNpZGVcbiAqIGFub3RoZXIgY2FsbGJhY2suIEEgY2FsbGJhY2sgaXMgYWx3YXlzIHJ1biBhc3luY2hyb25vdXNseSBzb21ldGltZSBhZnRlciB0aGVcbiAqIHNjb3BlIGNvbnRhaW5pbmcgdGhlIHJlZ2lzdGVyaW5nIHtAY29kZSB0aGVufSBpbnZvY2F0aW9uIGhhcyByZXR1cm5lZC5cbiAqXG4gKiBJZiBhIFByb21pc2UgaXMgcmVzb2x2ZWQgd2l0aCBhbm90aGVyIFByb21pc2UsIHRoZSBmaXJzdCBQcm9taXNlIHdpbGwgYmxvY2tcbiAqIHVudGlsIHRoZSBzZWNvbmQgaXMgcmVzb2x2ZWQsIGFuZCB0aGVuIGFzc3VtZXMgdGhlIHNhbWUgcmVzdWx0IGFzIHRoZSBzZWNvbmRcbiAqIFByb21pc2UuIFRoaXMgYWxsb3dzIFByb21pc2VzIHRvIGRlcGVuZCBvbiB0aGUgcmVzdWx0cyBvZiBvdGhlciBQcm9taXNlcyxcbiAqIGxpbmtpbmcgdG9nZXRoZXIgbXVsdGlwbGUgYXN5bmNocm9ub3VzIG9wZXJhdGlvbnMuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBjb21wYXRpYmxlIHdpdGggdGhlIFByb21pc2VzL0ErIHNwZWNpZmljYXRpb24gYW5kXG4gKiBwYXNzZXMgdGhhdCBzcGVjaWZpY2F0aW9uJ3MgY29uZm9ybWFuY2UgdGVzdCBzdWl0ZS4gQSBDbG9zdXJlIFByb21pc2UgbWF5IGJlXG4gKiByZXNvbHZlZCB3aXRoIGEgUHJvbWlzZSBpbnN0YW5jZSAob3Igc3VmZmljaWVudGx5IGNvbXBhdGlibGUgUHJvbWlzZS1saWtlXG4gKiBvYmplY3QpIGNyZWF0ZWQgYnkgb3RoZXIgUHJvbWlzZSBpbXBsZW1lbnRhdGlvbnMuIEZyb20gdGhlIHNwZWNpZmljYXRpb24sXG4gKiBQcm9taXNlLWxpa2Ugb2JqZWN0cyBhcmUga25vd24gYXMgXCJUaGVuYWJsZXNcIi5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9wcm9taXNlc2FwbHVzLmNvbS9cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFxuICogICAgICAgICAgICAgdGhpczpSRVNPTFZFUl9DT05URVhULFxuICogICAgICAgICAgICAgZnVuY3Rpb24oKFRZUEV8SVRoZW5hYmxlLjxUWVBFPnxUaGVuYWJsZSkpLFxuICogICAgICAgICAgICAgZnVuY3Rpb24oKikpOiB2b2lkfSByZXNvbHZlclxuICogICAgIEluaXRpYWxpemF0aW9uIGZ1bmN0aW9uIHRoYXQgaXMgaW52b2tlZCBpbW1lZGlhdGVseSB3aXRoIHtAY29kZSByZXNvbHZlfVxuICogICAgIGFuZCB7QGNvZGUgcmVqZWN0fSBmdW5jdGlvbnMgYXMgYXJndW1lbnRzLiBUaGUgUHJvbWlzZSBpcyByZXNvbHZlZCBvclxuICogICAgIHJlamVjdGVkIHdpdGggdGhlIGZpcnN0IGFyZ3VtZW50IHBhc3NlZCB0byBlaXRoZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge1JFU09MVkVSX0NPTlRFWFQ9fSBvcHRfY29udGV4dCBBbiBvcHRpb25hbCBjb250ZXh0IGZvciBleGVjdXRpbmcgdGhlXG4gKiAgICAgcmVzb2x2ZXIgZnVuY3Rpb24uIElmIHVuc3BlY2lmaWVkLCB0aGUgcmVzb2x2ZXIgZnVuY3Rpb24gd2lsbCBiZSBleGVjdXRlZFxuICogICAgIGluIHRoZSBkZWZhdWx0IHNjb3BlLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAc3RydWN0XG4gKiBAZmluYWxcbiAqIEBpbXBsZW1lbnRzIHtUaGVuYWJsZS48VFlQRT59XG4gKiBAdGVtcGxhdGUgVFlQRSxSRVNPTFZFUl9DT05URVhUXG4gKi9cbnZhciBDYW5jZWxsYWJsZVByb21pc2UgPSBmdW5jdGlvbihyZXNvbHZlciwgb3B0X2NvbnRleHQpIHtcbiAgLyoqXG4gICAqIFRoZSBpbnRlcm5hbCBzdGF0ZSBvZiB0aGlzIFByb21pc2UuIEVpdGhlciBQRU5ESU5HLCBGVUxGSUxMRUQsIFJFSkVDVEVELCBvclxuICAgKiBCTE9DS0VELlxuICAgKiBAcHJpdmF0ZSB7Q2FuY2VsbGFibGVQcm9taXNlLlN0YXRlX31cbiAgICovXG4gIHRoaXMuc3RhdGVfID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzb2x2ZWQgcmVzdWx0IG9mIHRoZSBQcm9taXNlLiBJbW11dGFibGUgb25jZSBzZXQgd2l0aCBlaXRoZXIgYVxuICAgKiBmdWxmaWxsbWVudCB2YWx1ZSBvciByZWplY3Rpb24gcmVhc29uLlxuICAgKiBAcHJpdmF0ZSB7Kn1cbiAgICovXG4gIHRoaXMucmVzdWx0XyA9IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogRm9yIFByb21pc2VzIGNyZWF0ZWQgYnkgY2FsbGluZyB7QGNvZGUgdGhlbigpfSwgdGhlIG9yaWdpbmF0aW5nIHBhcmVudC5cbiAgICogQHByaXZhdGUge0NhbmNlbGxhYmxlUHJvbWlzZX1cbiAgICovXG4gIHRoaXMucGFyZW50XyA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIHtAY29kZSBvbkZ1bGZpbGxlZH0gYW5kIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFja3MgYWRkZWQgdG9cbiAgICogdGhpcyBQcm9taXNlIGJ5IGNhbGxzIHRvIHtAY29kZSB0aGVuKCl9LlxuICAgKiBAcHJpdmF0ZSB7QXJyYXkuPENhbmNlbGxhYmxlUHJvbWlzZS5DYWxsYmFja0VudHJ5Xz59XG4gICAqL1xuICB0aGlzLmNhbGxiYWNrRW50cmllc18gPSBudWxsO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBQcm9taXNlIGlzIGluIHRoZSBxdWV1ZSBvZiBQcm9taXNlcyB0byBleGVjdXRlLlxuICAgKiBAcHJpdmF0ZSB7Ym9vbGVhbn1cbiAgICovXG4gIHRoaXMuZXhlY3V0aW5nXyA9IGZhbHNlO1xuXG4gIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA+IDApIHtcbiAgICAvKipcbiAgICAgKiBBIHRpbWVvdXQgSUQgdXNlZCB3aGVuIHRoZSB7QGNvZGUgVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWX0gaXMgZ3JlYXRlclxuICAgICAqIHRoYW4gMCBtaWxsaXNlY29uZHMuIFRoZSBJRCBpcyBzZXQgd2hlbiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCwgYW5kXG4gICAgICogY2xlYXJlZCBvbmx5IGlmIGFuIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayBpcyBpbnZva2VkIGZvciB0aGVcbiAgICAgKiBQcm9taXNlIChvciBvbmUgb2YgaXRzIGRlc2NlbmRhbnRzKSBiZWZvcmUgdGhlIGRlbGF5IGlzIGV4Y2VlZGVkLlxuICAgICAqXG4gICAgICogSWYgdGhlIHJlamVjdGlvbiBpcyBub3QgaGFuZGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQgY29tcGxldGVzLCB0aGVcbiAgICAgKiByZWplY3Rpb24gcmVhc29uIGlzIHBhc3NlZCB0byB0aGUgdW5oYW5kbGVkIHJlamVjdGlvbiBoYW5kbGVyLlxuICAgICAqIEBwcml2YXRlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy51bmhhbmRsZWRSZWplY3Rpb25JZF8gPSAwO1xuICB9IGVsc2UgaWYgKENhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID09PSAwKSB7XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUge0Bjb2RlIFVOSEFORExFRF9SRUpFQ1RJT05fREVMQVl9IGlzIHNldCB0byAwIG1pbGxpc2Vjb25kcywgYVxuICAgICAqIGJvb2xlYW4gdGhhdCBpcyBzZXQgaWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQsIGFuZCByZXNldCB0byBmYWxzZSBpZiBhblxuICAgICAqIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayBpcyBpbnZva2VkIGZvciB0aGUgUHJvbWlzZSAob3Igb25lIG9mIGl0c1xuICAgICAqIGRlc2NlbmRhbnRzKS4gSWYgdGhlIHJlamVjdGlvbiBpcyBub3QgaGFuZGxlZCBiZWZvcmUgdGhlIG5leHQgdGltZXN0ZXAsXG4gICAgICogdGhlIHJlamVjdGlvbiByZWFzb24gaXMgcGFzc2VkIHRvIHRoZSB1bmhhbmRsZWQgcmVqZWN0aW9uIGhhbmRsZXIuXG4gICAgICogQHByaXZhdGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5oYWRVbmhhbmRsZWRSZWplY3Rpb25fID0gZmFsc2U7XG4gIH1cblxuICB0cnkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXNvbHZlci5jYWxsKFxuICAgICAgb3B0X2NvbnRleHQsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHNlbGYucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5GVUxGSUxMRUQsIHZhbHVlKTtcbiAgICAgIH0sIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgICBzZWxmLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQsIHJlYXNvbik7XG4gICAgICB9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCwgZSk7XG4gIH1cbn07XG5cbi8qKlxuICogVGhlIGRlbGF5IGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgYSByZWplY3RlZCBQcm9taXNlJ3MgcmVhc29uIGlzIHBhc3NlZCB0b1xuICogdGhlIHJlamVjdGlvbiBoYW5kbGVyLiBCeSBkZWZhdWx0LCB0aGUgcmVqZWN0aW9uIGhhbmRsZXIgcmV0aHJvd3MgdGhlXG4gKiByZWplY3Rpb24gcmVhc29uIHNvIHRoYXQgaXQgYXBwZWFycyBpbiB0aGUgZGV2ZWxvcGVyIGNvbnNvbGUgb3JcbiAqIHtAY29kZSB3aW5kb3cub25lcnJvcn0gaGFuZGxlci5cbiAqIFJlamVjdGlvbnMgYXJlIHJldGhyb3duIGFzIHF1aWNrbHkgYXMgcG9zc2libGUgYnkgZGVmYXVsdC4gQSBuZWdhdGl2ZSB2YWx1ZVxuICogZGlzYWJsZXMgcmVqZWN0aW9uIGhhbmRsaW5nIGVudGlyZWx5LlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPSAwO1xuXG5cbi8qKlxuICogVGhlIHBvc3NpYmxlIGludGVybmFsIHN0YXRlcyBmb3IgYSBQcm9taXNlLiBUaGVzZSBzdGF0ZXMgYXJlIG5vdCBkaXJlY3RseVxuICogb2JzZXJ2YWJsZSB0byBleHRlcm5hbCBjYWxsZXJzLlxuICogQGVudW0ge251bWJlcn1cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8gPSB7XG4gIC8qKiBUaGUgUHJvbWlzZSBpcyB3YWl0aW5nIGZvciByZXNvbHV0aW9uLiAqL1xuICBQRU5ESU5HOiAwLFxuXG4gIC8qKiBUaGUgUHJvbWlzZSBpcyBibG9ja2VkIHdhaXRpbmcgZm9yIHRoZSByZXN1bHQgb2YgYW5vdGhlciBUaGVuYWJsZS4gKi9cbiAgQkxPQ0tFRDogMSxcblxuICAvKiogVGhlIFByb21pc2UgaGFzIGJlZW4gcmVzb2x2ZWQgd2l0aCBhIGZ1bGZpbGxtZW50IHZhbHVlLiAqL1xuICBGVUxGSUxMRUQ6IDIsXG5cbiAgLyoqIFRoZSBQcm9taXNlIGhhcyBiZWVuIHJlc29sdmVkIHdpdGggYSByZWplY3Rpb24gcmVhc29uLiAqL1xuICBSRUpFQ1RFRDogM1xufTtcblxuXG4vKipcbiAqIFR5cGVkZWYgZm9yIGVudHJpZXMgaW4gdGhlIGNhbGxiYWNrIGNoYWluLiBFYWNoIGNhbGwgdG8ge0Bjb2RlIHRoZW59LFxuICoge0Bjb2RlIHRoZW5DYXRjaH0sIG9yIHtAY29kZSB0aGVuQWx3YXlzfSBjcmVhdGVzIGFuIGVudHJ5IGNvbnRhaW5pbmcgdGhlXG4gKiBmdW5jdGlvbnMgdGhhdCBtYXkgYmUgaW52b2tlZCBvbmNlIHRoZSBQcm9taXNlIGlzIHJlc29sdmVkLlxuICpcbiAqIEB0eXBlZGVmIHt7XG4gKiAgIGNoaWxkOiBDYW5jZWxsYWJsZVByb21pc2UsXG4gKiAgIG9uRnVsZmlsbGVkOiBmdW5jdGlvbigqKSxcbiAqICAgb25SZWplY3RlZDogZnVuY3Rpb24oKilcbiAqIH19XG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV8gPSBudWxsO1xuXG5cbi8qKlxuICogQHBhcmFtIHsoVFlQRXxUaGVuYWJsZS48VFlQRT58VGhlbmFibGUpPX0gb3B0X3ZhbHVlXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlLjxUWVBFPn0gQSBuZXcgUHJvbWlzZSB0aGF0IGlzIGltbWVkaWF0ZWx5IHJlc29sdmVkXG4gKiAgICAgd2l0aCB0aGUgZ2l2ZW4gdmFsdWUuXG4gKiBAdGVtcGxhdGUgVFlQRVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSA9IGZ1bmN0aW9uKG9wdF92YWx1ZSkge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XG4gICAgICByZXNvbHZlKG9wdF92YWx1ZSk7XG4gICAgfSk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHsqPX0gb3B0X3JlYXNvblxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gQSBuZXcgUHJvbWlzZSB0aGF0IGlzIGltbWVkaWF0ZWx5IHJlamVjdGVkIHdpdGggdGhlXG4gKiAgICAgZ2l2ZW4gcmVhc29uLlxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24ob3B0X3JlYXNvbikge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHJlamVjdChvcHRfcmVhc29uKTtcbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0geyFBcnJheS48IShUaGVuYWJsZS48VFlQRT58VGhlbmFibGUpPn0gcHJvbWlzZXNcbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPFRZUEU+fSBBIFByb21pc2UgdGhhdCByZWNlaXZlcyB0aGUgcmVzdWx0IG9mIHRoZVxuICogICAgIGZpcnN0IFByb21pc2UgKG9yIFByb21pc2UtbGlrZSkgaW5wdXQgdG8gY29tcGxldGUuXG4gKiBAdGVtcGxhdGUgVFlQRVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucmFjZSA9IGZ1bmN0aW9uKHByb21pc2VzKSB7XG4gIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgaWYgKCFwcm9taXNlcy5sZW5ndGgpIHtcbiAgICAgICAgcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgaSA9IDAsIHByb21pc2U7IChwcm9taXNlID0gcHJvbWlzZXNbaV0pOyBpKyspIHtcbiAgICAgICAgcHJvbWlzZS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHshQXJyYXkuPCEoVGhlbmFibGUuPFRZUEU+fFRoZW5hYmxlKT59IHByb21pc2VzXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlLjwhQXJyYXkuPFRZUEU+Pn0gQSBQcm9taXNlIHRoYXQgcmVjZWl2ZXMgYSBsaXN0IG9mXG4gKiAgICAgZXZlcnkgZnVsZmlsbGVkIHZhbHVlIG9uY2UgZXZlcnkgaW5wdXQgUHJvbWlzZSAob3IgUHJvbWlzZS1saWtlKSBpc1xuICogICAgIHN1Y2Nlc3NmdWxseSBmdWxmaWxsZWQsIG9yIGlzIHJlamVjdGVkIGJ5IHRoZSBmaXJzdCByZWplY3Rpb24gcmVzdWx0LlxuICogQHRlbXBsYXRlIFRZUEVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLmFsbCA9IGZ1bmN0aW9uKHByb21pc2VzKSB7XG4gIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIHRvRnVsZmlsbCA9IHByb21pc2VzLmxlbmd0aDtcbiAgICAgIHZhciB2YWx1ZXMgPSBbXTtcblxuICAgICAgaWYgKCF0b0Z1bGZpbGwpIHtcbiAgICAgICAgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBvbkZ1bGZpbGwgPSBmdW5jdGlvbihpbmRleCwgdmFsdWUpIHtcbiAgICAgICAgdG9GdWxmaWxsLS07XG4gICAgICAgIHZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRvRnVsZmlsbCA9PT0gMCkge1xuICAgICAgICAgIHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgdmFyIG9uUmVqZWN0ID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgfTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIHByb21pc2U7IChwcm9taXNlID0gcHJvbWlzZXNbaV0pOyBpKyspIHtcbiAgICAgICAgcHJvbWlzZS50aGVuKHBhcnRpYWwob25GdWxmaWxsLCBpKSwgb25SZWplY3QpO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7IUFycmF5LjwhKFRoZW5hYmxlLjxUWVBFPnxUaGVuYWJsZSk+fSBwcm9taXNlc1xuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48VFlQRT59IEEgUHJvbWlzZSB0aGF0IHJlY2VpdmVzIHRoZSB2YWx1ZSBvZlxuICogICAgIHRoZSBmaXJzdCBpbnB1dCB0byBiZSBmdWxmaWxsZWQsIG9yIGlzIHJlamVjdGVkIHdpdGggYSBsaXN0IG9mIGV2ZXJ5XG4gKiAgICAgcmVqZWN0aW9uIHJlYXNvbiBpZiBhbGwgaW5wdXRzIGFyZSByZWplY3RlZC5cbiAqIEB0ZW1wbGF0ZSBUWVBFXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5maXJzdEZ1bGZpbGxlZCA9IGZ1bmN0aW9uKHByb21pc2VzKSB7XG4gIHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIHRvUmVqZWN0ID0gcHJvbWlzZXMubGVuZ3RoO1xuICAgICAgdmFyIHJlYXNvbnMgPSBbXTtcblxuICAgICAgaWYgKCF0b1JlamVjdCkge1xuICAgICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIG9uRnVsZmlsbCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgfTtcblxuICAgICAgdmFyIG9uUmVqZWN0ID0gZnVuY3Rpb24oaW5kZXgsIHJlYXNvbikge1xuICAgICAgICB0b1JlamVjdC0tO1xuICAgICAgICByZWFzb25zW2luZGV4XSA9IHJlYXNvbjtcbiAgICAgICAgaWYgKHRvUmVqZWN0ID09PSAwKSB7XG4gICAgICAgICAgcmVqZWN0KHJlYXNvbnMpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgcHJvbWlzZTsgKHByb21pc2UgPSBwcm9taXNlc1tpXSk7IGkrKykge1xuICAgICAgICBwcm9taXNlLnRoZW4ob25GdWxmaWxsLCBwYXJ0aWFsKG9uUmVqZWN0LCBpKSk7XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG5cbi8qKlxuICogQWRkcyBjYWxsYmFja3MgdGhhdCB3aWxsIG9wZXJhdGUgb24gdGhlIHJlc3VsdCBvZiB0aGUgUHJvbWlzZSwgcmV0dXJuaW5nIGFcbiAqIG5ldyBjaGlsZCBQcm9taXNlLlxuICpcbiAqIElmIHRoZSBQcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHtAY29kZSBvbkZ1bGZpbGxlZH0gY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VkXG4gKiB3aXRoIHRoZSBmdWxmaWxsbWVudCB2YWx1ZSBhcyBhcmd1bWVudCwgYW5kIHRoZSBjaGlsZCBQcm9taXNlIHdpbGwgYmVcbiAqIGZ1bGZpbGxlZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrLiBJZiB0aGUgY2FsbGJhY2sgdGhyb3dzIGFuXG4gKiBleGNlcHRpb24sIHRoZSBjaGlsZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgdGhyb3duIHZhbHVlIGluc3RlYWQuXG4gKlxuICogSWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQsIHRoZSB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VkXG4gKiB3aXRoIHRoZSByZWplY3Rpb24gcmVhc29uIGFzIGFyZ3VtZW50LCBhbmQgdGhlIGNoaWxkIFByb21pc2Ugd2lsbCBiZSByZWplY3RlZFxuICogd2l0aCB0aGUgcmV0dXJuIHZhbHVlIChvciB0aHJvd24gdmFsdWUpIG9mIHRoZSBjYWxsYmFjay5cbiAqXG4gKiBAb3ZlcnJpZGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24ob3B0X29uRnVsZmlsbGVkLCBvcHRfb25SZWplY3RlZCwgb3B0X2NvbnRleHQpIHtcbiAgcmV0dXJuIHRoaXMuYWRkQ2hpbGRQcm9taXNlXyhcbiAgICBpc0Z1bmN0aW9uKG9wdF9vbkZ1bGZpbGxlZCkgPyBvcHRfb25GdWxmaWxsZWQgOiBudWxsLFxuICAgIGlzRnVuY3Rpb24ob3B0X29uUmVqZWN0ZWQpID8gb3B0X29uUmVqZWN0ZWQgOiBudWxsLFxuICAgIG9wdF9jb250ZXh0KTtcbn07XG5UaGVuYWJsZS5hZGRJbXBsZW1lbnRhdGlvbihDYW5jZWxsYWJsZVByb21pc2UpO1xuXG5cbi8qKlxuICogQWRkcyBhIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBpbnZva2VkIHdoZXRoZXIgdGhlIFByb21pc2UgaXMgZnVsZmlsbGVkIG9yXG4gKiByZWplY3RlZC4gVGhlIGNhbGxiYWNrIHJlY2VpdmVzIG5vIGFyZ3VtZW50LCBhbmQgbm8gbmV3IGNoaWxkIFByb21pc2UgaXNcbiAqIGNyZWF0ZWQuIFRoaXMgaXMgdXNlZnVsIGZvciBlbnN1cmluZyB0aGF0IGNsZWFudXAgdGFrZXMgcGxhY2UgYWZ0ZXIgY2VydGFpblxuICogYXN5bmNocm9ub3VzIG9wZXJhdGlvbnMuIENhbGxiYWNrcyBhZGRlZCB3aXRoIHtAY29kZSB0aGVuQWx3YXlzfSB3aWxsIGJlXG4gKiBleGVjdXRlZCBpbiB0aGUgc2FtZSBvcmRlciB3aXRoIG90aGVyIGNhbGxzIHRvIHtAY29kZSB0aGVufSxcbiAqIHtAY29kZSB0aGVuQWx3YXlzfSwgb3Ige0Bjb2RlIHRoZW5DYXRjaH0uXG4gKlxuICogU2luY2UgaXQgZG9lcyBub3QgcHJvZHVjZSBhIG5ldyBjaGlsZCBQcm9taXNlLCBjYW5jZWxsYXRpb24gcHJvcGFnYXRpb24gaXNcbiAqIG5vdCBwcmV2ZW50ZWQgYnkgYWRkaW5nIGNhbGxiYWNrcyB3aXRoIHtAY29kZSB0aGVuQWx3YXlzfS4gQSBQcm9taXNlIHRoYXQgaGFzXG4gKiBhIGNsZWFudXAgaGFuZGxlciBhZGRlZCB3aXRoIHtAY29kZSB0aGVuQWx3YXlzfSB3aWxsIGJlIGNhbmNlbGVkIGlmIGFsbCBvZlxuICogaXRzIGNoaWxkcmVuIGNyZWF0ZWQgYnkge0Bjb2RlIHRoZW59IChvciB7QGNvZGUgdGhlbkNhdGNofSkgYXJlIGNhbmNlbGVkLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpUSElTKTogdm9pZH0gb25SZXNvbHZlZCBBIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBpbnZva2VkXG4gKiAgICAgd2hlbiB0aGUgUHJvbWlzZSBpcyByZXNvbHZlZC5cbiAqIEBwYXJhbSB7VEhJUz19IG9wdF9jb250ZXh0IEFuIG9wdGlvbmFsIGNvbnRleHQgb2JqZWN0IHRoYXQgd2lsbCBiZSB0aGVcbiAqICAgICBleGVjdXRpb24gY29udGV4dCBmb3IgdGhlIGNhbGxiYWNrcy4gQnkgZGVmYXVsdCwgZnVuY3Rpb25zIGFyZSBleGVjdXRlZFxuICogICAgIGluIHRoZSBnbG9iYWwgc2NvcGUuXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlLjxUWVBFPn0gVGhpcyBQcm9taXNlLCBmb3IgY2hhaW5pbmcgYWRkaXRpb25hbCBjYWxscy5cbiAqIEB0ZW1wbGF0ZSBUSElTXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbkFsd2F5cyA9IGZ1bmN0aW9uKG9uUmVzb2x2ZWQsIG9wdF9jb250ZXh0KSB7XG4gIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICAvLyBFbnN1cmUgdGhhdCBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCB0byBvblJlc29sdmVkLlxuICAgICAgb25SZXNvbHZlZC5jYWxsKG9wdF9jb250ZXh0KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIENhbmNlbGxhYmxlUHJvbWlzZS5oYW5kbGVSZWplY3Rpb25fLmNhbGwobnVsbCwgZXJyKTtcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5hZGRDYWxsYmFja0VudHJ5Xyh7XG4gICAgY2hpbGQ6IG51bGwsXG4gICAgb25SZWplY3RlZDogY2FsbGJhY2ssXG4gICAgb25GdWxmaWxsZWQ6IGNhbGxiYWNrXG4gIH0pO1xuICByZXR1cm4gdGhpcztcbn07XG5cblxuLyoqXG4gKiBBZGRzIGEgY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGludm9rZWQgb25seSBpZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZC4gVGhpc1xuICogaXMgZXF1aXZhbGVudCB0byB7QGNvZGUgdGhlbihudWxsLCBvblJlamVjdGVkKX0uXG4gKlxuICogQHBhcmFtIHshZnVuY3Rpb24odGhpczpUSElTLCAqKTogKn0gb25SZWplY3RlZCBBIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZVxuICogICAgIGludm9rZWQgd2l0aCB0aGUgcmVqZWN0aW9uIHJlYXNvbiBpZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZC5cbiAqIEBwYXJhbSB7VEhJUz19IG9wdF9jb250ZXh0IEFuIG9wdGlvbmFsIGNvbnRleHQgb2JqZWN0IHRoYXQgd2lsbCBiZSB0aGVcbiAqICAgICBleGVjdXRpb24gY29udGV4dCBmb3IgdGhlIGNhbGxiYWNrcy4gQnkgZGVmYXVsdCwgZnVuY3Rpb25zIGFyZSBleGVjdXRlZFxuICogICAgIGluIHRoZSBnbG9iYWwgc2NvcGUuXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlfSBBIG5ldyBQcm9taXNlIHRoYXQgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgb2YgdGhlXG4gKiAgICAgY2FsbGJhY2suXG4gKiBAdGVtcGxhdGUgVEhJU1xuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRoZW5DYXRjaCA9IGZ1bmN0aW9uKG9uUmVqZWN0ZWQsIG9wdF9jb250ZXh0KSB7XG4gIHJldHVybiB0aGlzLmFkZENoaWxkUHJvbWlzZV8obnVsbCwgb25SZWplY3RlZCwgb3B0X2NvbnRleHQpO1xufTtcblxuLyoqXG4gKiBBbGlhcyBvZiB7QGxpbmsgQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50aGVuQ2F0Y2h9XG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2ggPSBDYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRoZW5DYXRjaDtcblxuXG4vKipcbiAqIENhbmNlbHMgdGhlIFByb21pc2UgaWYgaXQgaXMgc3RpbGwgcGVuZGluZyBieSByZWplY3RpbmcgaXQgd2l0aCBhIGNhbmNlbFxuICogRXJyb3IuIE5vIGFjdGlvbiBpcyBwZXJmb3JtZWQgaWYgdGhlIFByb21pc2UgaXMgYWxyZWFkeSByZXNvbHZlZC5cbiAqXG4gKiBBbGwgY2hpbGQgUHJvbWlzZXMgb2YgdGhlIGNhbmNlbGVkIFByb21pc2Ugd2lsbCBiZSByZWplY3RlZCB3aXRoIHRoZSBzYW1lXG4gKiBjYW5jZWwgZXJyb3IsIGFzIHdpdGggbm9ybWFsIFByb21pc2UgcmVqZWN0aW9uLiBJZiB0aGUgUHJvbWlzZSB0byBiZSBjYW5jZWxlZFxuICogaXMgdGhlIG9ubHkgY2hpbGQgb2YgYSBwZW5kaW5nIFByb21pc2UsIHRoZSBwYXJlbnQgUHJvbWlzZSB3aWxsIGFsc28gYmVcbiAqIGNhbmNlbGVkLiBDYW5jZWxsYXRpb24gbWF5IHByb3BhZ2F0ZSB1cHdhcmQgdGhyb3VnaCBtdWx0aXBsZSBnZW5lcmF0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZz19IG9wdF9tZXNzYWdlIEFuIG9wdGlvbmFsIGRlYnVnZ2luZyBtZXNzYWdlIGZvciBkZXNjcmliaW5nIHRoZVxuICogICAgIGNhbmNlbGxhdGlvbiByZWFzb24uXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuY2FuY2VsID0gZnVuY3Rpb24ob3B0X21lc3NhZ2UpIHtcbiAgaWYgKHRoaXMuc3RhdGVfID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkcpIHtcbiAgICBhc3luYy5ydW4oZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZXJyID0gbmV3IENhbmNlbGxhYmxlUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvcihvcHRfbWVzc2FnZSk7XG4gICAgICBlcnIuSVNfQ0FOQ0VMTEFUSU9OX0VSUk9SID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2FuY2VsSW50ZXJuYWxfKGVycik7XG4gICAgfSwgdGhpcyk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBDYW5jZWxzIHRoaXMgUHJvbWlzZSB3aXRoIHRoZSBnaXZlbiBlcnJvci5cbiAqXG4gKiBAcGFyYW0geyFFcnJvcn0gZXJyIFRoZSBjYW5jZWxsYXRpb24gZXJyb3IuXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmNhbmNlbEludGVybmFsXyA9IGZ1bmN0aW9uKGVycikge1xuICBpZiAodGhpcy5zdGF0ZV8gPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORykge1xuICAgIGlmICh0aGlzLnBhcmVudF8pIHtcbiAgICAgIC8vIENhbmNlbCB0aGUgUHJvbWlzZSBhbmQgcmVtb3ZlIGl0IGZyb20gdGhlIHBhcmVudCdzIGNoaWxkIGxpc3QuXG4gICAgICB0aGlzLnBhcmVudF8uY2FuY2VsQ2hpbGRfKHRoaXMsIGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCwgZXJyKTtcbiAgICB9XG4gIH1cbn07XG5cblxuLyoqXG4gKiBDYW5jZWxzIGEgY2hpbGQgUHJvbWlzZSBmcm9tIHRoZSBsaXN0IG9mIGNhbGxiYWNrIGVudHJpZXMuIElmIHRoZSBQcm9taXNlIGhhc1xuICogbm90IGFscmVhZHkgYmVlbiByZXNvbHZlZCwgcmVqZWN0IGl0IHdpdGggYSBjYW5jZWwgZXJyb3IuIElmIHRoZXJlIGFyZSBub1xuICogb3RoZXIgY2hpbGRyZW4gaW4gdGhlIGxpc3Qgb2YgY2FsbGJhY2sgZW50cmllcywgcHJvcGFnYXRlIHRoZSBjYW5jZWxsYXRpb25cbiAqIGJ5IGNhbmNlbGluZyB0aGlzIFByb21pc2UgYXMgd2VsbC5cbiAqXG4gKiBAcGFyYW0geyFDYW5jZWxsYWJsZVByb21pc2V9IGNoaWxkUHJvbWlzZSBUaGUgUHJvbWlzZSB0byBjYW5jZWwuXG4gKiBAcGFyYW0geyFFcnJvcn0gZXJyIFRoZSBjYW5jZWwgZXJyb3IgdG8gdXNlIGZvciByZWplY3RpbmcgdGhlIFByb21pc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmNhbmNlbENoaWxkXyA9IGZ1bmN0aW9uKGNoaWxkUHJvbWlzZSwgZXJyKSB7XG4gIGlmICghdGhpcy5jYWxsYmFja0VudHJpZXNfKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjaGlsZENvdW50ID0gMDtcbiAgdmFyIGNoaWxkSW5kZXggPSAtMTtcblxuICAvLyBGaW5kIHRoZSBjYWxsYmFjayBlbnRyeSBmb3IgdGhlIGNoaWxkUHJvbWlzZSwgYW5kIGNvdW50IHdoZXRoZXIgdGhlcmUgYXJlXG4gIC8vIGFkZGl0aW9uYWwgY2hpbGQgUHJvbWlzZXMuXG4gIGZvciAodmFyIGkgPSAwLCBlbnRyeTsgKGVudHJ5ID0gdGhpcy5jYWxsYmFja0VudHJpZXNfW2ldKTsgaSsrKSB7XG4gICAgdmFyIGNoaWxkID0gZW50cnkuY2hpbGQ7XG4gICAgaWYgKGNoaWxkKSB7XG4gICAgICBjaGlsZENvdW50Kys7XG4gICAgICBpZiAoY2hpbGQgPT09IGNoaWxkUHJvbWlzZSkge1xuICAgICAgICBjaGlsZEluZGV4ID0gaTtcbiAgICAgIH1cbiAgICAgIGlmIChjaGlsZEluZGV4ID49IDAgJiYgY2hpbGRDb3VudCA+IDEpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgdGhlIGNoaWxkIFByb21pc2Ugd2FzIHRoZSBvbmx5IGNoaWxkLCBjYW5jZWwgdGhpcyBQcm9taXNlIGFzIHdlbGwuXG4gIC8vIE90aGVyd2lzZSwgcmVqZWN0IG9ubHkgdGhlIGNoaWxkIFByb21pc2Ugd2l0aCB0aGUgY2FuY2VsIGVycm9yLlxuICBpZiAoY2hpbGRJbmRleCA+PSAwKSB7XG4gICAgaWYgKHRoaXMuc3RhdGVfID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkcgJiYgY2hpbGRDb3VudCA9PT0gMSkge1xuICAgICAgdGhpcy5jYW5jZWxJbnRlcm5hbF8oZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGNhbGxiYWNrRW50cnkgPSB0aGlzLmNhbGxiYWNrRW50cmllc18uc3BsaWNlKGNoaWxkSW5kZXgsIDEpWzBdO1xuICAgICAgdGhpcy5leGVjdXRlQ2FsbGJhY2tfKFxuICAgICAgICBjYWxsYmFja0VudHJ5LCBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVELCBlcnIpO1xuICAgIH1cbiAgfVxufTtcblxuXG4vKipcbiAqIEFkZHMgYSBjYWxsYmFjayBlbnRyeSB0byB0aGUgY3VycmVudCBQcm9taXNlLCBhbmQgc2NoZWR1bGVzIGNhbGxiYWNrXG4gKiBleGVjdXRpb24gaWYgdGhlIFByb21pc2UgaGFzIGFscmVhZHkgYmVlbiByZXNvbHZlZC5cbiAqXG4gKiBAcGFyYW0ge0NhbmNlbGxhYmxlUHJvbWlzZS5DYWxsYmFja0VudHJ5X30gY2FsbGJhY2tFbnRyeSBSZWNvcmQgY29udGFpbmluZ1xuICogICAgIHtAY29kZSBvbkZ1bGZpbGxlZH0gYW5kIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFja3MgdG8gZXhlY3V0ZSBhZnRlclxuICogICAgIHRoZSBQcm9taXNlIGlzIHJlc29sdmVkLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5hZGRDYWxsYmFja0VudHJ5XyA9IGZ1bmN0aW9uKGNhbGxiYWNrRW50cnkpIHtcbiAgaWYgKCghdGhpcy5jYWxsYmFja0VudHJpZXNfIHx8ICF0aGlzLmNhbGxiYWNrRW50cmllc18ubGVuZ3RoKSAmJlxuICAgICh0aGlzLnN0YXRlXyA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5GVUxGSUxMRUQgfHxcbiAgICB0aGlzLnN0YXRlXyA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCkpIHtcbiAgICB0aGlzLnNjaGVkdWxlQ2FsbGJhY2tzXygpO1xuICB9XG4gIGlmICghdGhpcy5jYWxsYmFja0VudHJpZXNfKSB7XG4gICAgdGhpcy5jYWxsYmFja0VudHJpZXNfID0gW107XG4gIH1cbiAgdGhpcy5jYWxsYmFja0VudHJpZXNfLnB1c2goY2FsbGJhY2tFbnRyeSk7XG59O1xuXG5cbi8qKlxuICogQ3JlYXRlcyBhIGNoaWxkIFByb21pc2UgYW5kIGFkZHMgaXQgdG8gdGhlIGNhbGxiYWNrIGVudHJ5IGxpc3QuIFRoZSByZXN1bHQgb2ZcbiAqIHRoZSBjaGlsZCBQcm9taXNlIGlzIGRldGVybWluZWQgYnkgdGhlIHN0YXRlIG9mIHRoZSBwYXJlbnQgUHJvbWlzZSBhbmQgdGhlXG4gKiByZXN1bHQgb2YgdGhlIHtAY29kZSBvbkZ1bGZpbGxlZH0gb3Ige0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrcyBhc1xuICogc3BlY2lmaWVkIGluIHRoZSBQcm9taXNlIHJlc29sdXRpb24gcHJvY2VkdXJlLlxuICpcbiAqIEBzZWUgaHR0cDovL3Byb21pc2VzYXBsdXMuY29tLyN0aGVfX21ldGhvZFxuICpcbiAqIEBwYXJhbSB7P2Z1bmN0aW9uKHRoaXM6VEhJUywgVFlQRSk6XG4gKiAgICAgICAgICAoUkVTVUxUfENhbmNlbGxhYmxlUHJvbWlzZS48UkVTVUxUPnxUaGVuYWJsZSl9IG9uRnVsZmlsbGVkIEEgY2FsbGJhY2sgdGhhdFxuICogICAgIHdpbGwgYmUgaW52b2tlZCBpZiB0aGUgUHJvbWlzZSBpcyBmdWxsZmlsbGVkLCBvciBudWxsLlxuICogQHBhcmFtIHs/ZnVuY3Rpb24odGhpczpUSElTLCAqKTogKn0gb25SZWplY3RlZCBBIGNhbGxiYWNrIHRoYXQgd2lsbCBiZVxuICogICAgIGludm9rZWQgaWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQsIG9yIG51bGwuXG4gKiBAcGFyYW0ge1RISVM9fSBvcHRfY29udGV4dCBBbiBvcHRpb25hbCBleGVjdXRpb24gY29udGV4dCBmb3IgdGhlIGNhbGxiYWNrcy5cbiAqICAgICBpbiB0aGUgZGVmYXVsdCBjYWxsaW5nIGNvbnRleHQuXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlfSBUaGUgY2hpbGQgUHJvbWlzZS5cbiAqIEB0ZW1wbGF0ZSBSRVNVTFQsVEhJU1xuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5hZGRDaGlsZFByb21pc2VfID0gZnVuY3Rpb24oXG5vbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgb3B0X2NvbnRleHQpIHtcblxuICB2YXIgY2FsbGJhY2tFbnRyeSA9IHtcbiAgICBjaGlsZDogbnVsbCxcbiAgICBvbkZ1bGZpbGxlZDogbnVsbCxcbiAgICBvblJlamVjdGVkOiBudWxsXG4gIH07XG5cbiAgY2FsbGJhY2tFbnRyeS5jaGlsZCA9IG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgLy8gSW52b2tlIG9uRnVsZmlsbGVkLCBvciByZXNvbHZlIHdpdGggdGhlIHBhcmVudCdzIHZhbHVlIGlmIGFic2VudC5cbiAgICBjYWxsYmFja0VudHJ5Lm9uRnVsZmlsbGVkID0gb25GdWxmaWxsZWQgPyBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG9uRnVsZmlsbGVkLmNhbGwob3B0X2NvbnRleHQsIHZhbHVlKTtcbiAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfVxuICAgIH0gOiByZXNvbHZlO1xuXG4gICAgLy8gSW52b2tlIG9uUmVqZWN0ZWQsIG9yIHJlamVjdCB3aXRoIHRoZSBwYXJlbnQncyByZWFzb24gaWYgYWJzZW50LlxuICAgIGNhbGxiYWNrRW50cnkub25SZWplY3RlZCA9IG9uUmVqZWN0ZWQgPyBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBvblJlamVjdGVkLmNhbGwob3B0X2NvbnRleHQsIHJlYXNvbik7XG4gICAgICAgIGlmICghaXNEZWYocmVzdWx0KSAmJiByZWFzb24uSVNfQ0FOQ0VMTEFUSU9OX0VSUk9SKSB7XG4gICAgICAgICAgLy8gUHJvcGFnYXRlIGNhbmNlbGxhdGlvbiB0byBjaGlsZHJlbiBpZiBubyBvdGhlciByZXN1bHQgaXMgcmV0dXJuZWQuXG4gICAgICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9XG4gICAgfSA6IHJlamVjdDtcbiAgfSk7XG5cbiAgY2FsbGJhY2tFbnRyeS5jaGlsZC5wYXJlbnRfID0gdGhpcztcbiAgdGhpcy5hZGRDYWxsYmFja0VudHJ5XyhcbiAgICAvKiogQHR5cGUge0NhbmNlbGxhYmxlUHJvbWlzZS5DYWxsYmFja0VudHJ5X30gKi8gKGNhbGxiYWNrRW50cnkpKTtcbiAgcmV0dXJuIGNhbGxiYWNrRW50cnkuY2hpbGQ7XG59O1xuXG5cbi8qKlxuICogVW5ibG9ja3MgdGhlIFByb21pc2UgYW5kIGZ1bGZpbGxzIGl0IHdpdGggdGhlIGdpdmVuIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7VFlQRX0gdmFsdWVcbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudW5ibG9ja0FuZEZ1bGZpbGxfID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgaWYgKHRoaXMuc3RhdGVfICE9PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkJMT0NLRUQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbmNlbGxhYmxlUHJvbWlzZSBpcyBub3QgYmxvY2tlZC4nKTtcbiAgfVxuICB0aGlzLnN0YXRlXyA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORztcbiAgdGhpcy5yZXNvbHZlXyhDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkZVTEZJTExFRCwgdmFsdWUpO1xufTtcblxuXG4vKipcbiAqIFVuYmxvY2tzIHRoZSBQcm9taXNlIGFuZCByZWplY3RzIGl0IHdpdGggdGhlIGdpdmVuIHJlamVjdGlvbiByZWFzb24uXG4gKlxuICogQHBhcmFtIHsqfSByZWFzb25cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudW5ibG9ja0FuZFJlamVjdF8gPSBmdW5jdGlvbihyZWFzb24pIHtcbiAgaWYgKHRoaXMuc3RhdGVfICE9PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkJMT0NLRUQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbmNlbGxhYmxlUHJvbWlzZSBpcyBub3QgYmxvY2tlZC4nKTtcbiAgfVxuICB0aGlzLnN0YXRlXyA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORztcbiAgdGhpcy5yZXNvbHZlXyhDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVELCByZWFzb24pO1xufTtcblxuXG4vKipcbiAqIEF0dGVtcHRzIHRvIHJlc29sdmUgYSBQcm9taXNlIHdpdGggYSBnaXZlbiByZXNvbHV0aW9uIHN0YXRlIGFuZCB2YWx1ZS4gVGhpc1xuICogaXMgYSBuby1vcCBpZiB0aGUgZ2l2ZW4gUHJvbWlzZSBoYXMgYWxyZWFkeSBiZWVuIHJlc29sdmVkLlxuICpcbiAqIElmIHRoZSBnaXZlbiByZXN1bHQgaXMgYSBUaGVuYWJsZSAoc3VjaCBhcyBhbm90aGVyIFByb21pc2UpLCB0aGUgUHJvbWlzZSB3aWxsXG4gKiBiZSByZXNvbHZlZCB3aXRoIHRoZSBzYW1lIHN0YXRlIGFuZCByZXN1bHQgYXMgdGhlIFRoZW5hYmxlIG9uY2UgaXQgaXMgaXRzZWxmXG4gKiByZXNvbHZlZC5cbiAqXG4gKiBJZiB0aGUgZ2l2ZW4gcmVzdWx0IGlzIG5vdCBhIFRoZW5hYmxlLCB0aGUgUHJvbWlzZSB3aWxsIGJlIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQgd2l0aCB0aGF0IHJlc3VsdCBiYXNlZCBvbiB0aGUgZ2l2ZW4gc3RhdGUuXG4gKlxuICogQHNlZSBodHRwOi8vcHJvbWlzZXNhcGx1cy5jb20vI3RoZV9wcm9taXNlX3Jlc29sdXRpb25fcHJvY2VkdXJlXG4gKlxuICogQHBhcmFtIHtDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVffSBzdGF0ZVxuICogQHBhcmFtIHsqfSB4IFRoZSByZXN1bHQgdG8gYXBwbHkgdG8gdGhlIFByb21pc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnJlc29sdmVfID0gZnVuY3Rpb24oc3RhdGUsIHgpIHtcbiAgaWYgKHRoaXMuc3RhdGVfICE9PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodGhpcyA9PT0geCkge1xuICAgIHN0YXRlID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRDtcbiAgICB4ID0gbmV3IFR5cGVFcnJvcignQ2FuY2VsbGFibGVQcm9taXNlIGNhbm5vdCByZXNvbHZlIHRvIGl0c2VsZicpO1xuXG4gIH0gZWxzZSBpZiAoVGhlbmFibGUuaXNJbXBsZW1lbnRlZEJ5KHgpKSB7XG4gICAgeCA9IC8qKiBAdHlwZSB7IVRoZW5hYmxlfSAqLyAoeCk7XG4gICAgdGhpcy5zdGF0ZV8gPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkJMT0NLRUQ7XG4gICAgeC50aGVuKHRoaXMudW5ibG9ja0FuZEZ1bGZpbGxfLCB0aGlzLnVuYmxvY2tBbmRSZWplY3RfLCB0aGlzKTtcbiAgICByZXR1cm47XG5cbiAgfSBlbHNlIGlmIChpc09iamVjdCh4KSkge1xuICAgIHRyeSB7XG4gICAgICB2YXIgdGhlbiA9IHgudGhlbjtcbiAgICAgIGlmIChpc0Z1bmN0aW9uKHRoZW4pKSB7XG4gICAgICAgIHRoaXMudHJ5VGhlbl8oeCwgdGhlbik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzdGF0ZSA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQ7XG4gICAgICB4ID0gZTtcbiAgICB9XG4gIH1cblxuICB0aGlzLnJlc3VsdF8gPSB4O1xuICB0aGlzLnN0YXRlXyA9IHN0YXRlO1xuICB0aGlzLnNjaGVkdWxlQ2FsbGJhY2tzXygpO1xuXG4gIGlmIChzdGF0ZSA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCAmJiAheC5JU19DQU5DRUxMQVRJT05fRVJST1IpIHtcbiAgICBDYW5jZWxsYWJsZVByb21pc2UuYWRkVW5oYW5kbGVkUmVqZWN0aW9uXyh0aGlzLCB4KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEF0dGVtcHRzIHRvIGNhbGwgdGhlIHtAY29kZSB0aGVufSBtZXRob2Qgb24gYW4gb2JqZWN0IGluIHRoZSBob3BlcyB0aGF0IGl0IGlzXG4gKiBhIFByb21pc2UtY29tcGF0aWJsZSBpbnN0YW5jZS4gVGhpcyBhbGxvd3MgaW50ZXJvcGVyYXRpb24gYmV0d2VlbiBkaWZmZXJlbnRcbiAqIFByb21pc2UgaW1wbGVtZW50YXRpb25zLCBob3dldmVyIGEgbm9uLWNvbXBsaWFudCBvYmplY3QgbWF5IGNhdXNlIGEgUHJvbWlzZVxuICogdG8gaGFuZyBpbmRlZmluaXRlbHkuIElmIHRoZSB7QGNvZGUgdGhlbn0gbWV0aG9kIHRocm93cyBhbiBleGNlcHRpb24sIHRoZVxuICogZGVwZW5kZW50IFByb21pc2Ugd2lsbCBiZSByZWplY3RlZCB3aXRoIHRoZSB0aHJvd24gdmFsdWUuXG4gKlxuICogQHNlZSBodHRwOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTcwXG4gKlxuICogQHBhcmFtIHtUaGVuYWJsZX0gdGhlbmFibGUgQW4gb2JqZWN0IHdpdGggYSB7QGNvZGUgdGhlbn0gbWV0aG9kIHRoYXQgbWF5IGJlXG4gKiAgICAgY29tcGF0aWJsZSB3aXRoIHRoZSBQcm9taXNlL0ErIHNwZWNpZmljYXRpb24uXG4gKiBAcGFyYW0geyFGdW5jdGlvbn0gdGhlbiBUaGUge0Bjb2RlIHRoZW59IG1ldGhvZCBvZiB0aGUgVGhlbmFibGUgb2JqZWN0LlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50cnlUaGVuXyA9IGZ1bmN0aW9uKHRoZW5hYmxlLCB0aGVuKSB7XG4gIHRoaXMuc3RhdGVfID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5CTE9DS0VEO1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIHZhciBjYWxsZWQgPSBmYWxzZTtcblxuICB2YXIgcmVzb2x2ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICBwcm9taXNlLnVuYmxvY2tBbmRGdWxmaWxsXyh2YWx1ZSk7XG4gICAgfVxuICB9O1xuXG4gIHZhciByZWplY3QgPSBmdW5jdGlvbihyZWFzb24pIHtcbiAgICBpZiAoIWNhbGxlZCkge1xuICAgICAgY2FsbGVkID0gdHJ1ZTtcbiAgICAgIHByb21pc2UudW5ibG9ja0FuZFJlamVjdF8ocmVhc29uKTtcbiAgICB9XG4gIH07XG5cbiAgdHJ5IHtcbiAgICB0aGVuLmNhbGwodGhlbmFibGUsIHJlc29sdmUsIHJlamVjdCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZWplY3QoZSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBFeGVjdXRlcyB0aGUgcGVuZGluZyBjYWxsYmFja3Mgb2YgYSByZXNvbHZlZCBQcm9taXNlIGFmdGVyIGEgdGltZW91dC5cbiAqXG4gKiBTZWN0aW9uIDIuMi40IG9mIHRoZSBQcm9taXNlcy9BKyBzcGVjaWZpY2F0aW9uIHJlcXVpcmVzIHRoYXQgUHJvbWlzZVxuICogY2FsbGJhY2tzIG11c3Qgb25seSBiZSBpbnZva2VkIGZyb20gYSBjYWxsIHN0YWNrIHRoYXQgb25seSBjb250YWlucyBQcm9taXNlXG4gKiBpbXBsZW1lbnRhdGlvbiBjb2RlLCB3aGljaCB3ZSBhY2NvbXBsaXNoIGJ5IGludm9raW5nIGNhbGxiYWNrIGV4ZWN1dGlvbiBhZnRlclxuICogYSB0aW1lb3V0LiBJZiB7QGNvZGUgc3RhcnRFeGVjdXRpb25ffSBpcyBjYWxsZWQgbXVsdGlwbGUgdGltZXMgZm9yIHRoZSBzYW1lXG4gKiBQcm9taXNlLCB0aGUgY2FsbGJhY2sgY2hhaW4gd2lsbCBiZSBldmFsdWF0ZWQgb25seSBvbmNlLiBBZGRpdGlvbmFsIGNhbGxiYWNrc1xuICogbWF5IGJlIGFkZGVkIGR1cmluZyB0aGUgZXZhbHVhdGlvbiBwaGFzZSwgYW5kIHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIHNhbWVcbiAqIGV2ZW50IGxvb3AuXG4gKlxuICogQWxsIFByb21pc2VzIGFkZGVkIHRvIHRoZSB3YWl0aW5nIGxpc3QgZHVyaW5nIHRoZSBzYW1lIGJyb3dzZXIgZXZlbnQgbG9vcFxuICogd2lsbCBiZSBleGVjdXRlZCBpbiBvbmUgYmF0Y2ggdG8gYXZvaWQgdXNpbmcgYSBzZXBhcmF0ZSB0aW1lb3V0IHBlciBQcm9taXNlLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuc2NoZWR1bGVDYWxsYmFja3NfID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5leGVjdXRpbmdfKSB7XG4gICAgdGhpcy5leGVjdXRpbmdfID0gdHJ1ZTtcbiAgICBhc3luYy5ydW4odGhpcy5leGVjdXRlQ2FsbGJhY2tzXywgdGhpcyk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBFeGVjdXRlcyBhbGwgcGVuZGluZyBjYWxsYmFja3MgZm9yIHRoaXMgUHJvbWlzZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmV4ZWN1dGVDYWxsYmFja3NfID0gZnVuY3Rpb24oKSB7XG4gIHdoaWxlICh0aGlzLmNhbGxiYWNrRW50cmllc18gJiYgdGhpcy5jYWxsYmFja0VudHJpZXNfLmxlbmd0aCkge1xuICAgIHZhciBlbnRyaWVzID0gdGhpcy5jYWxsYmFja0VudHJpZXNfO1xuICAgIHRoaXMuY2FsbGJhY2tFbnRyaWVzXyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbnRyaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLmV4ZWN1dGVDYWxsYmFja18oZW50cmllc1tpXSwgdGhpcy5zdGF0ZV8sIHRoaXMucmVzdWx0Xyk7XG4gICAgfVxuICB9XG4gIHRoaXMuZXhlY3V0aW5nXyA9IGZhbHNlO1xufTtcblxuXG4vKipcbiAqIEV4ZWN1dGVzIGEgcGVuZGluZyBjYWxsYmFjayBmb3IgdGhpcyBQcm9taXNlLiBJbnZva2VzIGFuIHtAY29kZSBvbkZ1bGZpbGxlZH1cbiAqIG9yIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayBiYXNlZCBvbiB0aGUgcmVzb2x2ZWQgc3RhdGUgb2YgdGhlIFByb21pc2UuXG4gKlxuICogQHBhcmFtIHshQ2FuY2VsbGFibGVQcm9taXNlLkNhbGxiYWNrRW50cnlffSBjYWxsYmFja0VudHJ5IEFuIGVudHJ5IGNvbnRhaW5pbmcgdGhlXG4gKiAgICAgb25GdWxmaWxsZWQgYW5kL29yIG9uUmVqZWN0ZWQgY2FsbGJhY2tzIGZvciB0aGlzIHN0ZXAuXG4gKiBAcGFyYW0ge0NhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV99IHN0YXRlIFRoZSByZXNvbHV0aW9uIHN0YXR1cyBvZiB0aGUgUHJvbWlzZSxcbiAqICAgICBlaXRoZXIgRlVMRklMTEVEIG9yIFJFSkVDVEVELlxuICogQHBhcmFtIHsqfSByZXN1bHQgVGhlIHJlc29sdmVkIHJlc3VsdCBvZiB0aGUgUHJvbWlzZS5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuZXhlY3V0ZUNhbGxiYWNrXyA9IGZ1bmN0aW9uKFxuY2FsbGJhY2tFbnRyeSwgc3RhdGUsIHJlc3VsdCkge1xuICBpZiAoc3RhdGUgPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uRlVMRklMTEVEKSB7XG4gICAgY2FsbGJhY2tFbnRyeS5vbkZ1bGZpbGxlZChyZXN1bHQpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucmVtb3ZlVW5oYW5kbGVkUmVqZWN0aW9uXygpO1xuICAgIGNhbGxiYWNrRW50cnkub25SZWplY3RlZChyZXN1bHQpO1xuICB9XG59O1xuXG5cbi8qKlxuICogTWFya3MgdGhpcyByZWplY3RlZCBQcm9taXNlIGFzIGhhdmluZyBiZWluZyBoYW5kbGVkLiBBbHNvIG1hcmtzIGFueSBwYXJlbnRcbiAqIFByb21pc2VzIGluIHRoZSByZWplY3RlZCBzdGF0ZSBhcyBoYW5kbGVkLiBUaGUgcmVqZWN0aW9uIGhhbmRsZXIgd2lsbCBub1xuICogbG9uZ2VyIGJlIGludm9rZWQgZm9yIHRoaXMgUHJvbWlzZSAoaWYgaXQgaGFzIG5vdCBiZWVuIGNhbGxlZCBhbHJlYWR5KS5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnJlbW92ZVVuaGFuZGxlZFJlamVjdGlvbl8gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHA7XG4gIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA+IDApIHtcbiAgICBmb3IgKHAgPSB0aGlzOyBwICYmIHAudW5oYW5kbGVkUmVqZWN0aW9uSWRfOyBwID0gcC5wYXJlbnRfKSB7XG4gICAgICBjbGVhclRpbWVvdXQocC51bmhhbmRsZWRSZWplY3Rpb25JZF8pO1xuICAgICAgcC51bmhhbmRsZWRSZWplY3Rpb25JZF8gPSAwO1xuICAgIH1cbiAgfSBlbHNlIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA9PT0gMCkge1xuICAgIGZvciAocCA9IHRoaXM7IHAgJiYgcC5oYWRVbmhhbmRsZWRSZWplY3Rpb25fOyBwID0gcC5wYXJlbnRfKSB7XG4gICAgICBwLmhhZFVuaGFuZGxlZFJlamVjdGlvbl8gPSBmYWxzZTtcbiAgICB9XG4gIH1cbn07XG5cblxuLyoqXG4gKiBNYXJrcyB0aGlzIHJlamVjdGVkIFByb21pc2UgYXMgdW5oYW5kbGVkLiBJZiBubyB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tcbiAqIGlzIGNhbGxlZCBmb3IgdGhpcyBQcm9taXNlIGJlZm9yZSB0aGUge0Bjb2RlIFVOSEFORExFRF9SRUpFQ1RJT05fREVMQVl9XG4gKiBleHBpcmVzLCB0aGUgcmVhc29uIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSB1bmhhbmRsZWQgcmVqZWN0aW9uIGhhbmRsZXIuIFRoZVxuICogaGFuZGxlciB0eXBpY2FsbHkgcmV0aHJvd3MgdGhlIHJlamVjdGlvbiByZWFzb24gc28gdGhhdCBpdCBiZWNvbWVzIHZpc2libGUgaW5cbiAqIHRoZSBkZXZlbG9wZXIgY29uc29sZS5cbiAqXG4gKiBAcGFyYW0geyFDYW5jZWxsYWJsZVByb21pc2V9IHByb21pc2UgVGhlIHJlamVjdGVkIFByb21pc2UuXG4gKiBAcGFyYW0geyp9IHJlYXNvbiBUaGUgUHJvbWlzZSByZWplY3Rpb24gcmVhc29uLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLmFkZFVuaGFuZGxlZFJlamVjdGlvbl8gPSBmdW5jdGlvbihwcm9taXNlLCByZWFzb24pIHtcbiAgaWYgKENhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID4gMCkge1xuICAgIHByb21pc2UudW5oYW5kbGVkUmVqZWN0aW9uSWRfID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIENhbmNlbGxhYmxlUHJvbWlzZS5oYW5kbGVSZWplY3Rpb25fLmNhbGwobnVsbCwgcmVhc29uKTtcbiAgICB9LCBDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSk7XG5cbiAgfSBlbHNlIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA9PT0gMCkge1xuICAgIHByb21pc2UuaGFkVW5oYW5kbGVkUmVqZWN0aW9uXyA9IHRydWU7XG4gICAgYXN5bmMucnVuKGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHByb21pc2UuaGFkVW5oYW5kbGVkUmVqZWN0aW9uXykge1xuICAgICAgICBDYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXy5jYWxsKG51bGwsIHJlYXNvbik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBBIG1ldGhvZCB0aGF0IGlzIGludm9rZWQgd2l0aCB0aGUgcmVqZWN0aW9uIHJlYXNvbnMgZm9yIFByb21pc2VzIHRoYXQgYXJlXG4gKiByZWplY3RlZCBidXQgaGF2ZSBubyB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tzIHJlZ2lzdGVyZWQgeWV0LlxuICogQHR5cGUge2Z1bmN0aW9uKCopfVxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLmhhbmRsZVJlamVjdGlvbl8gPSBhc3luYy50aHJvd0V4Y2VwdGlvbjtcblxuXG4vKipcbiAqIFNldHMgYSBoYW5kbGVyIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2l0aCByZWFzb25zIGZyb20gdW5oYW5kbGVkIHJlamVjdGVkXG4gKiBQcm9taXNlcy4gSWYgdGhlIHJlamVjdGVkIFByb21pc2UgKG9yIG9uZSBvZiBpdHMgZGVzY2VuZGFudHMpIGhhcyBhblxuICoge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrIHJlZ2lzdGVyZWQsIHRoZSByZWplY3Rpb24gd2lsbCBiZSBjb25zaWRlcmVkXG4gKiBoYW5kbGVkLCBhbmQgdGhlIHJlamVjdGlvbiBoYW5kbGVyIHdpbGwgbm90IGJlIGNhbGxlZC5cbiAqXG4gKiBCeSBkZWZhdWx0LCB1bmhhbmRsZWQgcmVqZWN0aW9ucyBhcmUgcmV0aHJvd24gc28gdGhhdCB0aGUgZXJyb3IgbWF5IGJlXG4gKiBjYXB0dXJlZCBieSB0aGUgZGV2ZWxvcGVyIGNvbnNvbGUgb3IgYSB7QGNvZGUgd2luZG93Lm9uZXJyb3J9IGhhbmRsZXIuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbigqKX0gaGFuZGxlciBBIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2l0aCByZWFzb25zIGZyb21cbiAqICAgICByZWplY3RlZCBQcm9taXNlcy4gRGVmYXVsdHMgdG8ge0Bjb2RlIGFzeW5jLnRocm93RXhjZXB0aW9ufS5cbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnNldFVuaGFuZGxlZFJlamVjdGlvbkhhbmRsZXIgPSBmdW5jdGlvbihoYW5kbGVyKSB7XG4gIENhbmNlbGxhYmxlUHJvbWlzZS5oYW5kbGVSZWplY3Rpb25fID0gaGFuZGxlcjtcbn07XG5cblxuXG4vKipcbiAqIEVycm9yIHVzZWQgYXMgYSByZWplY3Rpb24gcmVhc29uIGZvciBjYW5jZWxlZCBQcm9taXNlcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZz19IG9wdF9tZXNzYWdlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIHtFcnJvcn1cbiAqIEBmaW5hbFxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IgPSBjbGFzcyBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3Iob3B0X21lc3NhZ2UpIHtcbiAgICAgc3VwZXIob3B0X21lc3NhZ2UpO1xuXG4gICAgIGlmIChvcHRfbWVzc2FnZSkge1xuICAgICAgIHRoaXMubWVzc2FnZSA9IG9wdF9tZXNzYWdlO1xuICAgICB9XG4gICB9XG59O1xuXG4vKiogQG92ZXJyaWRlICovXG5DYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IucHJvdG90eXBlLm5hbWUgPSAnY2FuY2VsJztcblxuZXhwb3J0IHtDYW5jZWxsYWJsZVByb21pc2V9O1xuZXhwb3J0IGRlZmF1bHQgQ2FuY2VsbGFibGVQcm9taXNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAgKiBEZWJvdW5jZXMgZnVuY3Rpb24gZXhlY3V0aW9uLlxuICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGZuXG4gICogQHBhcmFtIHtudW1iZXJ9IGRlbGF5XG4gICogQHJldHVybiB7IWZ1bmN0aW9uKCl9XG4gICovXG5mdW5jdGlvbiBkZWJvdW5jZShmbiwgZGVsYXkpIHtcblx0cmV0dXJuIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcblx0XHR2YXIgYXJncyA9IGFyZ3VtZW50cztcblx0XHRjYW5jZWxEZWJvdW5jZShkZWJvdW5jZWQpO1xuXHRcdGRlYm91bmNlZC5pZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRmbi5hcHBseShudWxsLCBhcmdzKTtcblx0XHR9LCBkZWxheSk7XG5cdH07XG59XG5cbi8qKlxuICogQ2FuY2VscyB0aGUgc2NoZWR1bGVkIGRlYm91bmNlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY2FuY2VsRGVib3VuY2UoZGVib3VuY2VkKSB7XG5cdGNsZWFyVGltZW91dChkZWJvdW5jZWQuaWQpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBkZWJvdW5jZTtcbmV4cG9ydCB7IGNhbmNlbERlYm91bmNlLCBkZWJvdW5jZSB9O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgY29yZSBmcm9tICdtZXRhbCc7XG5cbmNvbnN0IFJFR0VYID0gLyhbXFwvXSk/KD86KD86XFw6KFxcdyspKD86XFwoKCg/OlxcXFwufFteXFxcXCgpXSkqKVxcKSk/fFxcKCgoPzpcXFxcLnxbXlxcXFwoKV0pKylcXCkpKFsrKj9dKT8pL2c7XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIGFycmF5IG9mIHJlZ2V4IG1hdGNoZXMgdG8gYSBtb3JlIHJlYWRhYmxlIG9iamVjdCBmb3JtYXQuXG4gKiBAcGFyYW0geyFBcnJheTxzdHJpbmc+fSBtYXRjaGVzXG4gKiBAcmV0dXJuIHshT2JqZWN0fVxuICovXG5mdW5jdGlvbiBjb252ZXJ0TWF0Y2hlc1RvT2JqKG1hdGNoZXMpIHtcblx0cmV0dXJuIHtcblx0XHRtYXRjaDogbWF0Y2hlc1swXSxcblx0XHRwcmVmaXg6IG1hdGNoZXNbMV0sXG5cdFx0bmFtZTogbWF0Y2hlc1syXSxcblx0XHRwYXJhbVBhdHRlcm46IG1hdGNoZXNbM10sXG5cdFx0dW5uYW1lZFBhdHRlcm46IG1hdGNoZXNbNF0sXG5cdFx0bW9kaWZpZXI6IG1hdGNoZXNbNV1cblx0fTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gdG9rZW5zIHBhcnNlZCBmcm9tIGEgcm91dGUgZm9ybWF0IHN0cmluZyB0byBhIHJlZ2V4LlxuICogQHBhcmFtIHshQXJyYXk8c3RyaW5nfCFPYmplY3Q+fSB0b2tlbnNcbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRUb2tlbnNUb1JlZ2V4KHRva2Vucykge1xuXHRsZXQgcmVnZXggPSAnJztcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoY29yZS5pc1N0cmluZyh0b2tlbnNbaV0pKSB7XG5cdFx0XHRyZWdleCArPSBlc2NhcGUodG9rZW5zW2ldKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGV0IGNhcHR1cmUgPSBlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAodG9rZW5zW2ldLnBhdHRlcm4pO1xuXHRcdFx0aWYgKHRva2Vuc1tpXS5yZXBlYXQpIHtcblx0XHRcdFx0Y2FwdHVyZSArPSBlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAoJ1xcXFwvJyArIGNhcHR1cmUpICsgJyonO1xuXHRcdFx0fVxuXHRcdFx0Y2FwdHVyZSA9IGVzY2FwZSh0b2tlbnNbaV0ucHJlZml4KSArIGAoJHtjYXB0dXJlfSlgO1xuXHRcdFx0aWYgKHRva2Vuc1tpXS5vcHRpb25hbCkge1xuXHRcdFx0XHRpZiAoIXRva2Vuc1tpXS5wYXJ0aWFsKSB7XG5cdFx0XHRcdFx0Y2FwdHVyZSA9IGVuY2xvc2VOb25DYXB0dXJpbmdHcm91cChjYXB0dXJlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjYXB0dXJlICs9ICc/Jztcblx0XHRcdH1cblx0XHRcdHJlZ2V4ICs9IGNhcHR1cmU7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBuZXcgUmVnRXhwKCdeJyArIG1ha2VUcmFpbGluZ1NsYXNoT3B0aW9uYWwocmVnZXgpICsgJyQnKTtcbn1cblxuLyoqXG4gKiBFbmNsb3NlcyB0aGUgZ2l2ZW4gcmVnZXggcGF0dGVybiBpbnRvIGEgbm9uIGNhcHR1cmluZyBncm91cC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXR0ZXJuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVuY2xvc2VOb25DYXB0dXJpbmdHcm91cChwYXR0ZXJuKSB7XG5cdHJldHVybiBgKD86JHtwYXR0ZXJufSlgO1xufVxuXG4vKipcbiAqIEVzY2FwZXMgdGhlIGdpdmVuIHN0cmluZyB0byBzaG93IHVwIGluIHRoZSBwYXRoIHJlZ2V4LlxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBlc2NhcGUoc3RyKSB7XG5cdHJldHVybiBzdHIucmVwbGFjZSgvKFsuKyo/PV4hOiR7fSgpW1xcXXxcXC9cXFxcXSkvZywgJ1xcXFwkMScpO1xufVxuXG4vKipcbiAqIE1ha2VzIHRyYWlsaW5nIHNsYXNoIG9wdGlvbmFsIG9uIHBhdGhzLlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZ2V4XG4gKiBAcGFyYW0ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gbWFrZVRyYWlsaW5nU2xhc2hPcHRpb25hbChyZWdleCkge1xuXHRpZiAoL1xcLyQvLnRlc3QocmVnZXgpKSB7XG5cdFx0cmVnZXggKz0gJz8nO1xuXHR9IGVsc2Uge1xuXHRcdHJlZ2V4ICs9ICdcXFxcLz8nO1xuXHR9XG5cdHJldHVybiByZWdleDtcbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIGdpdmVuIHJvdXRlIGZvcm1hdCBzdHJpbmcgaW50byB0b2tlbnMgcmVwcmVzZW50aW5nIGl0cyBjb250ZW50cy5cbiAqIEBwYXJhbSB7IUFycmF5fHN0cmluZ30gcm91dGVPclRva2VucyBFaXRoZXIgYSByb3V0ZSBmb3JtYXQgc3RyaW5nIG9yIHRva2Vuc1xuICogICAgIHByZXZpb3VzbHkgcGFyc2VkIHZpYSB0aGUgYHBhcnNlYCBmdW5jdGlvbi5cbiAqIEByZXR1cm4geyFBcnJheTxzdHJpbmd8IU9iamVjdD59IEFuIGFycmF5IG9mIHRva2VucyB0aGF0IGNhbiBiZSBlaXRoZXIgcGxhaW5cbiAqICAgICBzdHJpbmdzIChwYXJ0IG9mIHRoZSByb3V0ZSkgb3Igb2JqZWN0cyBjb250YWluaW5nIGluZm9ybWF0aW9ucyBvbiBwYXJhbXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShyb3V0ZU9yVG9rZW5zKSB7XG5cdGlmICghY29yZS5pc1N0cmluZyhyb3V0ZU9yVG9rZW5zKSkge1xuXHRcdHJldHVybiByb3V0ZU9yVG9rZW5zO1xuXHR9XG5cblx0Y29uc3Qgcm91dGUgPSByb3V0ZU9yVG9rZW5zO1xuXHRsZXQgdW5uYW1lZENvdW50ID0gMDtcblx0Y29uc3QgdG9rZW5zID0gW107XG5cdGxldCBjdXJyUGF0aCA9ICcnO1xuXHRsZXQgaW5kZXggPSAwO1xuXG5cdGxldCBtYXRjaGVzID0gUkVHRVguZXhlYyhyb3V0ZSk7XG5cdHdoaWxlIChtYXRjaGVzKSB7XG5cdFx0Y29uc3QgZGF0YSA9IGNvbnZlcnRNYXRjaGVzVG9PYmoobWF0Y2hlcyk7XG5cblx0XHRjdXJyUGF0aCA9IHJvdXRlLnNsaWNlKGluZGV4LCBtYXRjaGVzLmluZGV4KTtcblx0XHRpbmRleCA9IG1hdGNoZXMuaW5kZXggKyBkYXRhLm1hdGNoLmxlbmd0aDtcblx0XHR0b2tlbnMucHVzaChjdXJyUGF0aCk7XG5cblx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRuYW1lOiBkYXRhLm5hbWUgPyBkYXRhLm5hbWUgOiAnJyArIHVubmFtZWRDb3VudCsrLFxuXHRcdFx0cGFydGlhbDogcm91dGVbaW5kZXhdICYmIHJvdXRlW2luZGV4XSAhPT0gZGF0YS5wcmVmaXgsXG5cdFx0XHRwcmVmaXg6IGRhdGEucHJlZml4IHx8ICcnLFxuXHRcdFx0cGF0dGVybjogZGF0YS5wYXJhbVBhdHRlcm4gfHwgZGF0YS51bm5hbWVkUGF0dGVybiB8fCAnW15cXFxcL10rJyxcblx0XHRcdHJlcGVhdDogZGF0YS5tb2RpZmllciA9PT0gJyonIHx8IGRhdGEubW9kaWZpZXIgPT09ICcrJyxcblx0XHRcdG9wdGlvbmFsOiBkYXRhLm1vZGlmaWVyID09PSAnKicgfHwgZGF0YS5tb2RpZmllciA9PT0gJz8nXG5cdFx0fSk7XG5cblx0XHRtYXRjaGVzID0gUkVHRVguZXhlYyhyb3V0ZSk7XG5cdH1cblxuXHRpZiAoaW5kZXggPCByb3V0ZS5sZW5ndGgpIHtcblx0XHR0b2tlbnMucHVzaChyb3V0ZS5zdWJzdHIoaW5kZXgpKTtcblx0fVxuXHRyZXR1cm4gdG9rZW5zO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiByb3V0ZSBmb3JtYXQgc3RyaW5nIHRvIGEgcmVnZXggdGhhdCBjYW4gZXh0cmFjdCBwYXJhbVxuICogZGF0YSBmcm9tIHBhdGhzIG1hdGNoaW5nIGl0LlxuICogQHBhcmFtIHshQXJyYXl8c3RyaW5nfSByb3V0ZU9yVG9rZW5zIEVpdGhlciBhIHJvdXRlIGZvcm1hdCBzdHJpbmcgb3IgdG9rZW5zXG4gKiAgICAgcHJldmlvdXNseSBwYXJzZWQgdmlhIHRoZSBgcGFyc2VgIGZ1bmN0aW9uLlxuICogQHJldHVybiB7IVJlZ0V4cH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvUmVnZXgocm91dGVPclRva2Vucykge1xuXHRyZXR1cm4gY29udmVydFRva2Vuc1RvUmVnZXgocGFyc2Uocm91dGVPclRva2VucykpO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIGRhdGEgZnJvbSB0aGUgZ2l2ZW4gcGF0aCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCByb3V0ZSBmb3JtYXQuXG4gKiBAcGFyYW0geyFBcnJheXxzdHJpbmd9IHJvdXRlT3JUb2tlbnMgRWl0aGVyIGEgcm91dGUgZm9ybWF0IHN0cmluZyBvciB0b2tlbnNcbiAqICAgICBwcmV2aW91c2x5IHBhcnNlZCB2aWEgdGhlIGBwYXJzZWAgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gVGhlIHBhdGggdG8gZXh0cmFjdCBwYXJhbSBkYXRhIGZyb20uXG4gKiBAcmV0dXJuIHtPYmplY3Q8c3RyaW5nLCBzdHJpbmc+fSBUaGUgZGF0YSBvYmplY3QsIG9yIG51bGwgaWYgdGhlIHBhdGggZG9lc24ndFxuICogICAgIG1hdGNoIHRoZSBnaXZlbiBmb3JtYXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0RGF0YShyb3V0ZU9yVG9rZW5zLCBwYXRoKSB7XG5cdGNvbnN0IGRhdGEgPSB7fTtcblx0Y29uc3QgdG9rZW5zID0gcGFyc2Uocm91dGVPclRva2Vucyk7XG5cdGNvbnN0IG1hdGNoID0gcGF0aC5tYXRjaChjb252ZXJ0VG9rZW5zVG9SZWdleCh0b2tlbnMpKTtcblxuXHRpZiAoIW1hdGNoKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHRsZXQgcGFyYW1JbmRleCA9IDE7XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKCFjb3JlLmlzU3RyaW5nKHRva2Vuc1tpXSkpIHtcblx0XHRcdGxldCB2YWx1ZSA9IG1hdGNoW3BhcmFtSW5kZXgrK107XG5cdFx0XHRpZiAoY29yZS5pc0RlZih2YWx1ZSkpIHtcblx0XHRcdFx0aWYgKHRva2Vuc1tpXS5yZXBlYXQpIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlLnNwbGl0KCcvJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YVt0b2tlbnNbaV0ubmFtZV0gPSB2YWx1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIGRhdGE7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGlzRGVmQW5kTm90TnVsbCwgaXNGdW5jdGlvbiwgaXNTdHJpbmcgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgeyBleHRyYWN0RGF0YSwgcGFyc2UsIHRvUmVnZXggfSBmcm9tICdtZXRhbC1wYXRoLXBhcnNlcic7XG5cbmNsYXNzIFJvdXRlIHtcblxuXHQvKipcblx0ICogUm91dGUgY2xhc3MuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ3xSZWdFeHB8RnVuY3Rpb259IHBhdGhcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGhhbmRsZXJcblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihwYXRoLCBoYW5kbGVyKSB7XG5cdFx0aWYgKCFpc0RlZkFuZE5vdE51bGwocGF0aCkpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignUm91dGUgcGF0aCBub3Qgc3BlY2lmaWVkLicpO1xuXHRcdH1cblx0XHRpZiAoIWlzRnVuY3Rpb24oaGFuZGxlcikpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignUm91dGUgaGFuZGxlciBpcyBub3QgYSBmdW5jdGlvbi4nKTtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBEZWZpbmVzIHRoZSBoYW5kbGVyIHdoaWNoIHdpbGwgZXhlY3V0ZSBvbmNlIGEgVVJMIGluIHRoZSBhcHBsaWNhdGlvblxuXHRcdCAqIG1hdGNoZXMgdGhlIHBhdGguXG5cdFx0ICogQHR5cGUgeyFGdW5jdGlvbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcblxuXHRcdC8qKlxuXHRcdCAqIERlZmluZXMgdGhlIHBhdGggd2hpY2ggd2lsbCB0cmlnZ2VyIHRoZSByb3V0ZSBoYW5kbGVyLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfFJlZ0V4cHxGdW5jdGlvbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5wYXRoID0gcGF0aDtcblx0fVxuXG5cdC8qKlxuXHQqIEJ1aWxkcyBwYXJzZWQgZGF0YSAocmVnZXggYW5kIHRva2VucykgZm9yIHRoaXMgcm91dGUuXG5cdCogQHJldHVybiB7IU9iamVjdH1cblx0KiBAcHJvdGVjdGVkXG5cdCovXG5cdGJ1aWxkUGFyc2VkRGF0YV8oKSB7XG5cdFx0aWYgKCF0aGlzLnBhcnNlZERhdGFfKSB7XG5cdFx0XHR2YXIgdG9rZW5zID0gcGFyc2UodGhpcy5wYXRoKTtcblx0XHRcdHZhciByZWdleCA9IHRvUmVnZXgodG9rZW5zKTtcblx0XHRcdHRoaXMucGFyc2VkRGF0YV8gPSB7XG5cdFx0XHRcdHJlZ2V4LFxuXHRcdFx0XHR0b2tlbnNcblx0XHRcdH07XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLnBhcnNlZERhdGFfO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIHBhcmFtIGRhdGEgZnJvbSB0aGUgZ2l2ZW4gcGF0aCwgYWNjb3JkaW5nIHRvIHRoaXMgcm91dGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSB1cmwgcGF0aCB0byBleHRyYWN0IHBhcmFtcyBmcm9tLlxuXHQgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBleHRyYWN0ZWQgZGF0YSwgaWYgdGhlIHBhdGggbWF0Y2hlcyB0aGlzIHJvdXRlLCBvclxuXHQgKiAgICAgbnVsbCBvdGhlcndpc2UuXG5cdCAqL1xuXHRleHRyYWN0UGFyYW1zKHBhdGgpIHtcblx0XHRpZiAoaXNTdHJpbmcodGhpcy5wYXRoKSkge1xuXHRcdFx0cmV0dXJuIGV4dHJhY3REYXRhKHRoaXMuYnVpbGRQYXJzZWREYXRhXygpLnRva2VucywgcGF0aCk7XG5cdFx0fVxuXHRcdHJldHVybiB7fTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSByb3V0ZSBoYW5kbGVyLlxuXHQgKiBAcmV0dXJuIHshRnVuY3Rpb259XG5cdCAqL1xuXHRnZXRIYW5kbGVyKCkge1xuXHRcdHJldHVybiB0aGlzLmhhbmRsZXI7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcm91dGUgcGF0aC5cblx0ICogQHJldHVybiB7IXN0cmluZ3xSZWdFeHB8RnVuY3Rpb259XG5cdCAqL1xuXHRnZXRQYXRoKCkge1xuXHRcdHJldHVybiB0aGlzLnBhdGg7XG5cdH1cblxuXHQvKipcbiBcdCAqIE1hdGNoZXMgaWYgdGhlIHJvdXRlciBjYW4gaGFuZGxlIHRoZSB0ZXN0ZWQgcGF0aC5cbiBcdCAqIEBwYXJhbSB7IXN0cmluZ30gdmFsdWUgUGF0aCB0byB0ZXN0IChtYXkgY29udGFpbiB0aGUgcXVlcnlzdHJpbmcgcGFydCkuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFJldHVybnMgdHJ1ZSBpZiBtYXRjaGVzIGFueSByb3V0ZS5cblx0ICovXG5cdG1hdGNoZXNQYXRoKHZhbHVlKSB7XG5cdFx0dmFyIHBhdGggPSB0aGlzLnBhdGg7XG5cblx0XHRpZiAoaXNGdW5jdGlvbihwYXRoKSkge1xuXHRcdFx0cmV0dXJuIHBhdGgodmFsdWUpO1xuXHRcdH1cblx0XHRpZiAoaXNTdHJpbmcocGF0aCkpIHtcblx0XHRcdHBhdGggPSB0aGlzLmJ1aWxkUGFyc2VkRGF0YV8oKS5yZWdleDtcblx0XHR9XG5cdFx0aWYgKHBhdGggaW5zdGFuY2VvZiBSZWdFeHApIHtcblx0XHRcdHJldHVybiB2YWx1ZS5zZWFyY2gocGF0aCkgPiAtMTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBSb3V0ZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgRGlzcG9zYWJsZSB9IGZyb20gJ21ldGFsJztcblxuY2xhc3MgQ2FjaGVhYmxlIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cblx0LyoqXG5cdCAqIEFic3RyYWN0IGNsYXNzIGZvciBkZWZpbmluZyBjYWNoZWFibGUgYmVoYXZpb3IuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBjYWNoZWQgZGF0YS5cblx0XHQgKiBAdHlwZSB7IU9iamVjdH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuY2FjaGUgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgd2hldGhlciBjbGFzcyBpcyBjYWNoZWFibGUuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgZmFsc2Vcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5jYWNoZWFibGUgPSBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGNvbnRlbnQgdG8gdGhlIGNhY2hlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudCBDb250ZW50IHRvIGJlIGNhY2hlZC5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkQ2FjaGUoY29udGVudCkge1xuXHRcdGlmICh0aGlzLmNhY2hlYWJsZSkge1xuXHRcdFx0dGhpcy5jYWNoZSA9IGNvbnRlbnQ7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFycyB0aGUgY2FjaGUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGNsZWFyQ2FjaGUoKSB7XG5cdFx0dGhpcy5jYWNoZSA9IG51bGw7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLmNsZWFyQ2FjaGUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBjYWNoZWQgY29udGVudC5cblx0ICogQHJldHVybiB7T2JqZWN0fSBDYWNoZWQgY29udGVudC5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0Z2V0Q2FjaGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuY2FjaGU7XG5cdH1cblxuXHQvKipcblx0ICogV2hldGhlciB0aGUgY2xhc3MgaXMgY2FjaGVhYmxlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgd2hlbiBjbGFzcyBpcyBjYWNoZWFibGUsIGZhbHNlIG90aGVyd2lzZS5cblx0ICovXG5cdGlzQ2FjaGVhYmxlKCkge1xuXHRcdHJldHVybiB0aGlzLmNhY2hlYWJsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHdoZXRoZXIgdGhlIGNsYXNzIGlzIGNhY2hlYWJsZS5cblx0ICogQHBhcmFtIHtib29sZWFufSBjYWNoZWFibGVcblx0ICovXG5cdHNldENhY2hlYWJsZShjYWNoZWFibGUpIHtcblx0XHRpZiAoIWNhY2hlYWJsZSkge1xuXHRcdFx0dGhpcy5jbGVhckNhY2hlKCk7XG5cdFx0fVxuXHRcdHRoaXMuY2FjaGVhYmxlID0gY2FjaGVhYmxlO1xuXHR9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2FjaGVhYmxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgeyBnbG9iYWxFdmFsIH0gZnJvbSAnbWV0YWwtZG9tJztcbmltcG9ydCBDYWNoZWFibGUgZnJvbSAnLi4vY2FjaGVhYmxlL0NhY2hlYWJsZSc7XG5pbXBvcnQgQ2FuY2VsbGFibGVQcm9taXNlIGZyb20gJ21ldGFsLXByb21pc2UnO1xuXG5jbGFzcyBTY3JlZW4gZXh0ZW5kcyBDYWNoZWFibGUge1xuXG5cdC8qKlxuXHQgKiBTY3JlZW4gY2xhc3MgaXMgYSBzcGVjaWFsIHR5cGUgb2Ygcm91dGUgaGFuZGxlciB0aGF0IHByb3ZpZGVzIGhlbHBlclxuXHQgKiB1dGlsaXRpZXMgdGhhdCBhZGRzIGxpZmVjeWNsZSBhbmQgbWV0aG9kcyB0byBwcm92aWRlIGNvbnRlbnQgdG8gZWFjaFxuXHQgKiByZWdpc3RlcmVkIHN1cmZhY2UuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAZXh0ZW5kcyB7Q2FjaGVhYmxlfVxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBzY3JlZW4gaWQuXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5pZCA9IHRoaXMubWFrZUlkXyhnZXRVaWQoKSk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgc2NyZWVuIG1ldGEgdGFncy4gUmVsZXZhbnQgd2hlbiB0aGUgbWV0YSB0YWdzXG5cdFx0ICogc2hvdWxkIGJlIHVwZGF0ZWQgd2hlbiBzY3JlZW4gaXMgcmVuZGVyZWQuXG5cdFx0ICovXG5cdFx0dGhpcy5tZXRhcyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgc2NyZWVuIHRpdGxlLiBSZWxldmFudCB3aGVuIHRoZSBwYWdlIHRpdGxlIHNob3VsZCBiZVxuXHRcdCAqIHVwYWRhdGVkIHdoZW4gc2NyZWVuIGlzIHJlbmRlcmVkLlxuXHRcdCAqIEB0eXBlIHs/c3RyaW5nPX1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMudGl0bGUgPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEZpcmVzIHdoZW4gdGhlIHNjcmVlbiBpcyBhY3RpdmUuIEFsbG93cyBhIHNjcmVlbiB0byBwZXJmb3JtIGFueSBzZXR1cFxuXHQgKiB0aGF0IHJlcXVpcmVzIGl0cyBET00gdG8gYmUgdmlzaWJsZS4gTGlmZWN5Y2xlLlxuXHQgKi9cblx0YWN0aXZhdGUoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBhY3RpdmF0ZScpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdpdmVzIHRoZSBTY3JlZW4gYSBjaGFuY2UgdG8gY2FuY2VsIHRoZSBuYXZpZ2F0aW9uIGFuZCBzdG9wIGl0c2VsZiBmcm9tXG5cdCAqIGFjdGl2YXRpbmcuIENhbiBiZSB1c2VkLCBmb3IgZXhhbXBsZSwgdG8gcHJldmVudCBuYXZpZ2F0aW9uIGlmIGEgdXNlclxuXHQgKiBpcyBub3QgYXV0aGVudGljYXRlZC4gTGlmZWN5Y2xlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFuPXw/Q2FuY2VsbGFibGVQcm9taXNlPX0gSWYgcmV0dXJucyBvciByZXNvbHZlcyB0byB0cnVlLFxuXHQgKiAgICAgdGhlIGN1cnJlbnQgc2NyZWVuIGlzIGxvY2tlZCBhbmQgdGhlIG5leHQgbmFnaXZhdGlvbiBpbnRlcnJ1cHRlZC5cblx0ICovXG5cdGJlZm9yZUFjdGl2YXRlKCkge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gYmVmb3JlQWN0aXZhdGUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHaXZlcyB0aGUgU2NyZWVuIGEgY2hhbmNlIHRvIGNhbmNlbCB0aGUgbmF2aWdhdGlvbiBhbmQgc3RvcCBpdHNlbGYgZnJvbVxuXHQgKiBiZWluZyBkZWFjdGl2YXRlZC4gQ2FuIGJlIHVzZWQsIGZvciBleGFtcGxlLCBpZiB0aGUgc2NyZWVuIGhhcyB1bnNhdmVkXG5cdCAqIHN0YXRlLiBMaWZlY3ljbGUuIENsZWFuLXVwIHNob3VsZCBub3QgYmUgcHJlZm9ybWVkIGhlcmUsIHNpbmNlIHRoZVxuXHQgKiBuYXZpZ2F0aW9uIG1heSBzdGlsbCBiZSBjYW5jZWxsZWQuIERvIGNsZWFuLXVwIGluIGRlYWN0aXZhdGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW49fD9DYW5jZWxsYWJsZVByb21pc2U9fSBJZiByZXR1cm5zIG9yIHJlc29sdmVzIHRvIHRydWUsXG5cdCAqICAgICB0aGUgY3VycmVudCBzY3JlZW4gaXMgbG9ja2VkIGFuZCB0aGUgbmV4dCBuYWdpdmF0aW9uIGludGVycnVwdGVkLlxuXHQgKi9cblx0YmVmb3JlRGVhY3RpdmF0ZSgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGJlZm9yZURlYWN0aXZhdGUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHaXZlcyB0aGUgU2NyZWVuIGEgY2hhbmNlIGZvcm1hdCB0aGUgcGF0aCBiZWZvcmUgaGlzdG9yeSB1cGRhdGUuXG5cdCAqIEBwYXRoIHshc3RyaW5nfSBwYXRoIE5hdmlnYXRpb24gcGF0aC5cblx0ICogQHJldHVybiB7IXN0cmluZ30gTmF2aWdhdGlvbiBwYXRoIHRvIHVzZSBvbiBoaXN0b3J5LlxuXHQgKi9cblx0YmVmb3JlVXBkYXRlSGlzdG9yeVBhdGgocGF0aCkge1xuXHRcdHJldHVybiBwYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdpdmVzIHRoZSBTY3JlZW4gYSBjaGFuY2UgZm9ybWF0IHRoZSBzdGF0ZSBiZWZvcmUgaGlzdG9yeSB1cGRhdGUuXG5cdCAqIEBwYXRoIHshb2JqZWN0fSBzdGF0ZSBIaXN0b3J5IHN0YXRlLlxuXHQgKiBAcmV0dXJuIHshb2JqZWN0fSBIaXN0b3J5IHN0YXRlIHRvIHVzZSBvbiBoaXN0b3J5LlxuXHQgKi9cblx0YmVmb3JlVXBkYXRlSGlzdG9yeVN0YXRlKHN0YXRlKSB7XG5cdFx0cmV0dXJuIHN0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFsbG93cyBhIHNjcmVlbiB0byBkbyBhbnkgY2xlYW51cCBuZWNlc3NhcnkgYWZ0ZXIgaXQgaGFzIGJlZW5cblx0ICogZGVhY3RpdmF0ZWQsIGZvciBleGFtcGxlIGNhbmNlbGxpbmcgb3V0c3RhbmRpbmcgcmVxdWVzdHMgb3Igc3RvcHBpbmdcblx0ICogdGltZXJzLiBMaWZlY3ljbGUuXG5cdCAqL1xuXHRkZWFjdGl2YXRlKCkge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gZGVhY3RpdmF0ZScpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2UgYSBzY3JlZW4sIGVpdGhlciBhZnRlciBpdCBpcyBkZWFjdGl2YXRlZCAoaW4gdGhlIGNhc2Ugb2YgYVxuXHQgKiBub24tY2FjaGVhYmxlIHZpZXcpIG9yIHdoZW4gdGhlIEFwcCBpcyBpdHNlbGYgZGlzcG9zZWQgZm9yIHdoYXRldmVyXG5cdCAqIHJlYXNvbi4gTGlmZWN5Y2xlLlxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHN1cGVyLmRpc3Bvc2VJbnRlcm5hbCgpO1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gZGlzcG9zZScpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFsbG93cyBhIHNjcmVlbiB0byBldmFsdWF0ZSBzY3JpcHRzIGJlZm9yZSB0aGUgZWxlbWVudCBpcyBtYWRlIHZpc2libGUuXG5cdCAqIExpZmVjeWNsZS5cblx0ICogQHBhcmFtIHshb2JqZWN0fSBzdXJmYWNlcyBNYXAgb2Ygc3VyZmFjZXMgdG8gZmxpcCBrZXllZCBieSBzdXJmYWNlIGlkLlxuXHQgKiBAcmV0dXJuIHs/Q2FuY2VsbGFibGVQcm9taXNlPX0gVGhpcyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggd2lsbFxuXHQgKiAgICAgcGF1c2UgdGhlIG5hdmlnYXRpb24gdW50aWwgaXQgaXMgcmVzb2x2ZWQuXG5cdCAqL1xuXHRldmFsdWF0ZVNjcmlwdHMoc3VyZmFjZXMpIHtcblx0XHRPYmplY3Qua2V5cyhzdXJmYWNlcykuZm9yRWFjaChzSWQgPT4ge1xuXHRcdFx0aWYgKHN1cmZhY2VzW3NJZF0uYWN0aXZlQ2hpbGQpIHtcblx0XHRcdFx0Z2xvYmFsRXZhbC5ydW5TY3JpcHRzSW5FbGVtZW50KHN1cmZhY2VzW3NJZF0uYWN0aXZlQ2hpbGQpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFsbG93cyBhIHNjcmVlbiB0byBldmFsdWF0ZSBzdHlsZXMgYmVmb3JlIHRoZSBlbGVtZW50IGlzIG1hZGUgdmlzaWJsZS5cblx0ICogTGlmZWN5Y2xlLlxuXHQgKiBAcGFyYW0geyFvYmplY3R9IHN1cmZhY2VzIE1hcCBvZiBzdXJmYWNlcyB0byBmbGlwIGtleWVkIGJ5IHN1cmZhY2UgaWQuXG5cdCAqIEByZXR1cm4gez9DYW5jZWxsYWJsZVByb21pc2U9fSBUaGlzIGNhbiByZXR1cm4gYSBwcm9taXNlLCB3aGljaCB3aWxsXG5cdCAqICAgICBwYXVzZSB0aGUgbmF2aWdhdGlvbiB1bnRpbCBpdCBpcyByZXNvbHZlZC5cblx0ICovXG5cdGV2YWx1YXRlU3R5bGVzKCkge1xuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFsbG93cyBhIHNjcmVlbiB0byBwZXJmb3JtIGFueSBzZXR1cCBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGVsZW1lbnQgaXNcblx0ICogbWFkZSB2aXNpYmxlLiBMaWZlY3ljbGUuXG5cdCAqIEBwYXJhbSB7IW9iamVjdH0gc3VyZmFjZXMgTWFwIG9mIHN1cmZhY2VzIHRvIGZsaXAga2V5ZWQgYnkgc3VyZmFjZSBpZC5cblx0ICogQHJldHVybiB7P0NhbmNlbGxhYmxlUHJvbWlzZT19IFRoaXMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIHdpbGwgcGF1c2UgdGhlXG5cdCAqICAgICBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0ZmxpcChzdXJmYWNlcykge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gZmxpcCcpO1xuXG5cdFx0dmFyIHRyYW5zaXRpb25zID0gW107XG5cblx0XHRPYmplY3Qua2V5cyhzdXJmYWNlcykuZm9yRWFjaChzSWQgPT4ge1xuXHRcdFx0dmFyIHN1cmZhY2UgPSBzdXJmYWNlc1tzSWRdO1xuXHRcdFx0dmFyIGRlZmVycmVkID0gc3VyZmFjZS5zaG93KHRoaXMuaWQpO1xuXHRcdFx0dHJhbnNpdGlvbnMucHVzaChkZWZlcnJlZCk7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLmFsbCh0cmFuc2l0aW9ucyk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2NyZWVuIGlkLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRJZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5pZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzY3JlZW4gbWV0YSB0YWdzLlxuXHQgKiBAcmV0dXJuIHtOb2RlTGlzdHxOb2RlfVxuXHQgKi9cblx0Z2V0TWV0YXMoKSB7XG5cdFx0cmV0dXJuIHRoaXMubWV0YXM7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgY29udGVudCBmb3IgdGhlIGdpdmVuIHN1cmZhY2UsIG9yIG51bGwgaWYgdGhlIHN1cmZhY2UgaXNuJ3Rcblx0ICogdXNlZCBieSB0aGlzIHNjcmVlbi4gVGhpcyB3aWxsIGJlIGNhbGxlZCB3aGVuIGEgc2NyZWVuIGlzIGluaXRpYWxseVxuXHQgKiBjb25zdHJ1Y3RlZCBvciwgaWYgYSBzY3JlZW4gaXMgbm9uLWNhY2hlYWJsZSwgd2hlbiBuYXZpZ2F0ZWQuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc3VyZmFjZUlkIFRoZSBpZCBvZiB0aGUgc3VyZmFjZSBET00gZWxlbWVudC5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBwYXJhbXMgUGFyYW1zIGV4dHJhY3RlZCBmcm9tIHRoZSBjdXJyZW50IHBhdGguXG5cdCAqIEByZXR1cm4gez9zdHJpbmd8RWxlbWVudD19IFRoaXMgY2FuIHJldHVybiBhIHN0cmluZyBvciBub2RlIHJlcHJlc2VudGluZ1xuXHQgKiAgICAgdGhlIGNvbnRlbnQgb2YgdGhlIHN1cmZhY2UuIElmIHJldHVybnMgZmFsc3kgdmFsdWVzIHN1cmZhY2UgZGVmYXVsdFxuXHQgKiAgICAgY29udGVudCBpcyByZXN0b3JlZC5cblx0ICovXG5cdGdldFN1cmZhY2VDb250ZW50KCkge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gZ2V0U3VyZmFjZUNvbnRlbnQnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzY3JlZW4gdGl0bGUuXG5cdCAqIEByZXR1cm4gez9zdHJpbmc9fVxuXHQgKi9cblx0Z2V0VGl0bGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMudGl0bGU7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhbGwgY29udGVudHMgZm9yIHRoZSBzdXJmYWNlcy4gVGhpcyB3aWxsIHBhc3MgdGhlIGxvYWRlZCBjb250ZW50XG5cdCAqIHRvIDxjb2RlPlNjcmVlbi5sb2FkPC9jb2RlPiB3aXRoIGFsbCBpbmZvcm1hdGlvbiB5b3Vcblx0ICogbmVlZCB0byBmdWxmaWxsIHRoZSBzdXJmYWNlcy4gTGlmZWN5Y2xlLlxuXHQgKiBAcGFyYW0geyFzdHJpbmc9fSBwYXRoIFRoZSByZXF1ZXN0ZWQgcGF0aC5cblx0ICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gVGhpcyBjYW4gcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGVcblx0ICogICAgIGNvbnRlbnRzIG9mIHRoZSBzdXJmYWNlcyBvciBhIHByb21pc2UsIHdoaWNoIHdpbGwgcGF1c2UgdGhlIG5hdmlnYXRpb25cblx0ICogICAgIHVudGlsIGl0IGlzIHJlc29sdmVkLiBUaGlzIGlzIHVzZWZ1bCBmb3IgbG9hZGluZyBhc3luYyBjb250ZW50LlxuXHQgKi9cblx0bG9hZCgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGxvYWQnKTtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYWtlcyB0aGUgaWQgZm9yIHRoZSBzY3JlZW4uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaWQgVGhlIHNjcmVlbiBpZCB0aGUgY29udGVudCBiZWxvbmdzIHRvby5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0bWFrZUlkXyhpZCkge1xuXHRcdHJldHVybiAnc2NyZWVuXycgKyBpZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzY3JlZW4gaWQuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaWRcblx0ICovXG5cdHNldElkKGlkKSB7XG5cdFx0dGhpcy5pZCA9IGlkO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHNjcmVlbiBtZXRhIHRhZ3MuXG5cdCAqIEBwYXJhbSB7Tm9kZUxpc3R8Tm9kZX0gbWV0YXNcblx0ICovXG5cdHNldE1ldGFzKG1ldGFzKSB7XG5cdFx0dGhpcy5tZXRhcyA9IG1ldGFzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHNjcmVlbiB0aXRsZS5cblx0ICogQHBhcmFtIHs/c3RyaW5nPX0gdGl0bGVcblx0ICovXG5cdHNldFRpdGxlKHRpdGxlKSB7XG5cdFx0dGhpcy50aXRsZSA9IHRpdGxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiB0aGlzLmlkO1xuXHR9XG5cbn1cblxuLyoqXG4gKiBAcGFyYW0geyp9IG9iamVjdFxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciBhIGdpdmVuIGluc3RhbmNlIGltcGxlbWVudHNcbiAqIDxjb2RlPlNjcmVlbjwvY29kZT4uXG4gKi9cblNjcmVlbi5pc0ltcGxlbWVudGVkQnkgPSBmdW5jdGlvbihvYmplY3QpIHtcblx0cmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIFNjcmVlbjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNjcmVlbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGdsb2JhbHMgZnJvbSAnLi4vZ2xvYmFscy9nbG9iYWxzJztcbmltcG9ydCB7IERpc3Bvc2FibGUsIGlzRGVmQW5kTm90TnVsbCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IGFwcGVuZCwgcmVtb3ZlQ2hpbGRyZW4sIGV4aXREb2N1bWVudCB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgQ2FuY2VsbGFibGVQcm9taXNlIGZyb20gJ21ldGFsLXByb21pc2UnO1xuXG5jbGFzcyBTdXJmYWNlIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cblx0LyoqXG5cdCAqIFN1cmZhY2UgY2xhc3MgcmVwcmVzZW50aW5nIHRoZSByZWZlcmVuY2VzIHRvIGVsZW1lbnRzIG9uIHRoZSBwYWdlIHRoYXRcblx0ICogY2FuIHBvdGVudGlhbGx5IGJlIHVwZGF0ZWQgYnkgPGNvZGU+QXBwPC9jb2RlPi5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGlkXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoaWQpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0aWYgKCFpZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdTdXJmYWNlIGVsZW1lbnQgaWQgbm90IHNwZWNpZmllZC4gQSBzdXJmYWNlIGVsZW1lbnQgcmVxdWlyZXMgYSB2YWxpZCBpZC4nKTtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgYWN0aXZlIGNoaWxkIGVsZW1lbnQuXG5cdFx0ICogQHR5cGUge0VsZW1lbnR9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmFjdGl2ZUNoaWxkID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBkZWZhdWx0IGNoaWxkIGVsZW1lbnQuXG5cdFx0ICogQHR5cGUge0VsZW1lbnR9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmRlZmF1bHRDaGlsZCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgc3VyZmFjZSBpZCwgaWYgbm90IGZvdW5kIGNyZWF0ZXMgYVxuXHRcdCAqIG5ldyBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCBpZC5cblx0XHQgKiBAdHlwZSB7RWxlbWVudH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZWxlbWVudCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgc3VyZmFjZSBpZC5cblx0XHQgKiBAdHlwZSB7U3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5pZCA9IGlkO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGRlZmF1bHQgdHJhbnNpdGlvbkZuIGZvciB0aGUgc3VyZmFjZXMuXG5cdFx0ICogQHBhcmFtIHs/RWxlbWVudD19IGZyb20gVGhlIHZpc2libGUgc3VyZmFjZSBlbGVtZW50LlxuXHRcdCAqIEBwYXJhbSB7P0VsZW1lbnQ9fSB0byBUaGUgc3VyZmFjZSBlbGVtZW50IHRvIGJlIGZsaXBwZWQuXG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqL1xuXHRcdHRoaXMudHJhbnNpdGlvbkZuID0gbnVsbDtcblxuXHRcdHRoaXMuZGVmYXVsdENoaWxkID0gdGhpcy5nZXRDaGlsZChTdXJmYWNlLkRFRkFVTFQpO1xuXHRcdHRoaXMubWF5YmVXcmFwQ29udGVudEFzRGVmYXVsdF8oKTtcblx0XHR0aGlzLmFjdGl2ZUNoaWxkID0gdGhpcy5kZWZhdWx0Q2hpbGQ7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBzY3JlZW4gY29udGVudCB0byBhIHN1cmZhY2UuIElmIGNvbnRlbnQgaGFzbid0IGJlZW4gcGFzc2VkLCBzZWUgaWZcblx0ICogYW4gZWxlbWVudCBleGlzdHMgaW4gdGhlIERPTSB0aGF0IG1hdGNoZXMgdGhlIGlkLiBCeSBjb252ZW50aW9uLCB0aGVcblx0ICogZWxlbWVudCBzaG91bGQgYWxyZWFkeSBiZSBuZXN0ZWQgaW4gdGhlIHJpZ2h0IGVsZW1lbnQgYW5kIHNob3VsZCBoYXZlIGFuXG5cdCAqIGlkIHRoYXQgaXMgYSBjb25jYXRlbnRhdGlvbiBvZiB0aGUgc3VyZmFjZSBpZCArICctJyArIHRoZSBzY3JlZW4gaWQuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2NyZWVuSWQgVGhlIHNjcmVlbiBpZCB0aGUgY29udGVudCBiZWxvbmdzIHRvby5cblx0ICogQHBhcmFtIHs/c3RyaW5nfEVsZW1lbnQ9fSBvcHRfY29udGVudCBUaGUgc3RyaW5nIGNvbnRlbnQgb3IgZWxlbWVudCB0b1xuXHQgKiAgICAgYWRkIGJlIGFkZGVkIGFzIHN1cmZhY2UgY29udGVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH1cblx0ICovXG5cdGFkZENvbnRlbnQoc2NyZWVuSWQsIG9wdF9jb250ZW50KSB7XG5cdFx0dmFyIGNoaWxkID0gdGhpcy5kZWZhdWx0Q2hpbGQ7XG5cblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKG9wdF9jb250ZW50KSkge1xuXHRcdFx0Y2hpbGQgPSB0aGlzLmdldENoaWxkKHNjcmVlbklkKTtcblx0XHRcdGlmIChjaGlsZCkge1xuXHRcdFx0XHRyZW1vdmVDaGlsZHJlbihjaGlsZCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjaGlsZCA9IHRoaXMuY3JlYXRlQ2hpbGQoc2NyZWVuSWQpO1xuXHRcdFx0XHR0aGlzLnRyYW5zaXRpb24oY2hpbGQsIG51bGwpO1xuXHRcdFx0fVxuXHRcdFx0YXBwZW5kKGNoaWxkLCBvcHRfY29udGVudCk7XG5cdFx0fVxuXG5cdFx0dmFyIGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnQoKTtcblxuXHRcdGlmIChlbGVtZW50ICYmIGNoaWxkKSB7XG5cdFx0XHRhcHBlbmQoZWxlbWVudCwgY2hpbGQpO1xuXHRcdH1cblxuXHRcdHJldHVybiBjaGlsZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGNoaWxkIG5vZGUgZm9yIHRoZSBzdXJmYWNlLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQuXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9XG5cdCAqL1xuXHRjcmVhdGVDaGlsZChzY3JlZW5JZCkge1xuXHRcdHZhciBjaGlsZCA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0Y2hpbGQuc2V0QXR0cmlidXRlKCdpZCcsIHRoaXMubWFrZUlkXyhzY3JlZW5JZCkpO1xuXHRcdHJldHVybiBjaGlsZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIGNoaWxkIG5vZGUgb2YgdGhlIHN1cmZhY2UuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2NyZWVuSWQgVGhlIHNjcmVlbiBpZC5cblx0ICogQHJldHVybiB7P0VsZW1lbnR9XG5cdCAqL1xuXHRnZXRDaGlsZChzY3JlZW5JZCkge1xuXHRcdHJldHVybiBnbG9iYWxzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMubWFrZUlkXyhzY3JlZW5JZCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHN1cmZhY2UgZWxlbWVudCBmcm9tIGVsZW1lbnQsIGFuZCBzZXRzIGl0IHRvIHRoZSBlbCBwcm9wZXJ0eSBvZlxuXHQgKiB0aGUgY3VycmVudCBpbnN0YW5jZS5cblx0ICogPGNvZGU+dGhpcy5lbGVtZW50PC9jb2RlPiB3aWxsIGJlIHVzZWQuXG5cdCAqIEByZXR1cm4gez9FbGVtZW50fSBUaGUgY3VycmVudCBzdXJmYWNlIGVsZW1lbnQuXG5cdCAqL1xuXHRnZXRFbGVtZW50KCkge1xuXHRcdGlmICh0aGlzLmVsZW1lbnQpIHtcblx0XHRcdHJldHVybiB0aGlzLmVsZW1lbnQ7XG5cdFx0fVxuXHRcdHRoaXMuZWxlbWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pZCk7XG5cdFx0cmV0dXJuIHRoaXMuZWxlbWVudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzdXJmYWNlIGlkLlxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9XG5cdCAqL1xuXHRnZXRJZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5pZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzdXJmYWNlIHRyYW5zaXRpb24gZnVuY3Rpb24uXG5cdCAqIFNlZSA8Y29kZT5TdXJmYWNlLmRlZmF1bHRUcmFuc2l0aW9uPC9jb2RlPi5cblx0ICogQHJldHVybiB7P0Z1bmN0aW9uPX0gVGhlIHRyYW5zaXRpb24gZnVuY3Rpb24uXG5cdCAqL1xuXHRnZXRUcmFuc2l0aW9uRm4oKSB7XG5cdFx0cmV0dXJuIHRoaXMudHJhbnNpdGlvbkZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1ha2VzIHRoZSBpZCBmb3IgdGhlIGVsZW1lbnQgdGhhdCBob2xkcyBjb250ZW50IGZvciBhIHNjcmVlbi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkIHRoZSBjb250ZW50IGJlbG9uZ3MgdG9vLlxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRtYWtlSWRfKHNjcmVlbklkKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQgKyAnLScgKyBzY3JlZW5JZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBJZiBkZWZhdWx0IGNoaWxkIGlzIG1pc3NpbmcsIHdyYXBzIHN1cmZhY2UgY29udGVudCBhcyBkZWZhdWx0IGNoaWxkLiBJZlxuXHQgKiBzdXJmYWNlIGhhdmUgc3RhdGljIGNvbnRlbnQsIG1ha2Ugc3VyZSB0byBwbGFjZSBhXG5cdCAqIDxjb2RlPnN1cmZhY2VJZC1kZWZhdWx0PC9jb2RlPiBlbGVtZW50IGluc2lkZSBzdXJmYWNlLCBvbmx5IGNvbnRlbnRzXG5cdCAqIGluc2lkZSB0aGUgZGVmYXVsdCBjaGlsZCB3aWxsIGJlIHJlcGxhY2VkIGJ5IG5hdmlnYXRpb24uXG5cdCAqL1xuXHRtYXliZVdyYXBDb250ZW50QXNEZWZhdWx0XygpIHtcblx0XHR2YXIgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudCgpO1xuXHRcdGlmIChlbGVtZW50ICYmICF0aGlzLmRlZmF1bHRDaGlsZCkge1xuXHRcdFx0dmFyIGZyYWdtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG5cdFx0XHR3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7XG5cdFx0XHRcdGZyYWdtZW50LmFwcGVuZENoaWxkKGVsZW1lbnQuZmlyc3RDaGlsZCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmRlZmF1bHRDaGlsZCA9IHRoaXMuYWRkQ29udGVudChTdXJmYWNlLkRFRkFVTFQsIGZyYWdtZW50KTtcblx0XHRcdHRoaXMudHJhbnNpdGlvbihudWxsLCB0aGlzLmRlZmF1bHRDaGlsZCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHN1cmZhY2UgaWQuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaWRcblx0ICovXG5cdHNldElkKGlkKSB7XG5cdFx0dGhpcy5pZCA9IGlkO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHN1cmZhY2UgdHJhbnNpdGlvbiBmdW5jdGlvbi5cblx0ICogU2VlIDxjb2RlPlN1cmZhY2UuZGVmYXVsdFRyYW5zaXRpb248L2NvZGU+LlxuXHQgKiBAcGFyYW0gez9GdW5jdGlvbj19IHRyYW5zaXRpb25GbiBUaGUgdHJhbnNpdGlvbiBmdW5jdGlvbi5cblx0ICovXG5cdHNldFRyYW5zaXRpb25Gbih0cmFuc2l0aW9uRm4pIHtcblx0XHR0aGlzLnRyYW5zaXRpb25GbiA9IHRyYW5zaXRpb25Gbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBTaG93cyBzY3JlZW4gY29udGVudCBmcm9tIGEgc3VyZmFjZS5cblx0ICogQHBhcmFtIHtTdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQgdG8gc2hvdy5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfSBQYXVzZXMgdGhlIG5hdmlnYXRpb24gdW50aWwgaXQgaXMgcmVzb2x2ZWQuXG5cdCAqL1xuXHRzaG93KHNjcmVlbklkKSB7XG5cdFx0dmFyIGZyb20gPSB0aGlzLmFjdGl2ZUNoaWxkO1xuXHRcdHZhciB0byA9IHRoaXMuZ2V0Q2hpbGQoc2NyZWVuSWQpO1xuXHRcdGlmICghdG8pIHtcblx0XHRcdHRvID0gdGhpcy5kZWZhdWx0Q2hpbGQ7XG5cdFx0fVxuXHRcdHRoaXMuYWN0aXZlQ2hpbGQgPSB0bztcblx0XHRyZXR1cm4gdGhpcy50cmFuc2l0aW9uKGZyb20sIHRvKS50aGVuQWx3YXlzKCgpID0+IHtcblx0XHRcdGlmIChmcm9tICYmIGZyb20gIT09IHRvKSB7XG5cdFx0XHRcdGV4aXREb2N1bWVudChmcm9tKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHNjcmVlbiBjb250ZW50IGZyb20gYSBzdXJmYWNlLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQgdG8gcmVtb3ZlLlxuXHQgKi9cblx0cmVtb3ZlKHNjcmVlbklkKSB7XG5cdFx0dmFyIGNoaWxkID0gdGhpcy5nZXRDaGlsZChzY3JlZW5JZCk7XG5cdFx0aWYgKGNoaWxkKSB7XG5cdFx0XHRleGl0RG9jdW1lbnQoY2hpbGQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9XG5cdCAqL1xuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gdGhpcy5pZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBJbnZva2VzIHRoZSB0cmFuc2l0aW9uIGZ1bmN0aW9uIHNwZWNpZmllZCBvbiA8Y29kZT50cmFuc2l0aW9uPC9jb2RlPiBhdHRyaWJ1dGUuXG5cdCAqIEBwYXJhbSB7P0VsZW1lbnQ9fSBmcm9tXG5cdCAqIEBwYXJhbSB7P0VsZW1lbnQ9fSB0b1xuXHQgKiBAcmV0dXJuIHs/Q2FuY2VsbGFibGVQcm9taXNlPX0gVGhpcyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggd2lsbCBwYXVzZSB0aGVcblx0ICogICAgIG5hdmlnYXRpb24gdW50aWwgaXQgaXMgcmVzb2x2ZWQuXG5cdCAqL1xuXHR0cmFuc2l0aW9uKGZyb20sIHRvKSB7XG5cdFx0dmFyIHRyYW5zaXRpb25GbiA9IHRoaXMudHJhbnNpdGlvbkZuIHx8IFN1cmZhY2UuZGVmYXVsdFRyYW5zaXRpb247XG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKHRyYW5zaXRpb25Gbi5jYWxsKHRoaXMsIGZyb20sIHRvKSk7XG5cdH1cblxufVxuXG4vKipcbiAgICogSG9sZHMgdGhlIGRlZmF1bHQgc3VyZmFjZSBuYW1lLiBFbGVtZW50cyBvbiB0aGUgcGFnZSBtdXN0IGNvbnRhaW4gYSBjaGlsZFxuICAgKiBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGRlZmF1bHQgY29udGVudCwgdGhpcyBlbGVtZW50IG11c3QgYmUgYXMgZm9sbG93aW5nOlxuICAgKlxuICAgKiBFeGFtcGxlOlxuICAgKiA8Y29kZT5cbiAgICogICA8ZGl2IGlkPVwibXlzdXJmYWNlXCI+XG4gICAqICAgICA8ZGl2IGlkPVwibXlzdXJmYWNlLWRlZmF1bHRcIj5EZWZhdWx0IHN1cmZhY2UgY29udGVudC48L2Rpdj5cbiAgICogICA8L2Rpdj5cbiAgICogPC9jb2RlPlxuICAgKlxuICAgKiBUaGUgZGVmYXVsdCBjb250ZW50IGlzIHJlbGV2YW50IGZvciB0aGUgaW5pdGlhbCBwYWdlIGNvbnRlbnQuIFdoZW4gYVxuICAgKiBzY3JlZW4gZG9lc24ndCBwcm92aWRlIGNvbnRlbnQgZm9yIHRoZSBzdXJmYWNlIHRoZSBkZWZhdWx0IGNvbnRlbnQgaXNcbiAgICogcmVzdG9yZWQgaW50byB0aGUgcGFnZS5cbiAgICpcbiAgICogQHR5cGUgeyFTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQHN0YXRpY1xuICAgKi9cblN1cmZhY2UuREVGQVVMVCA9ICdkZWZhdWx0JztcblxuLyoqXG4gKiBIb2xkcyB0aGUgZGVmYXVsdCB0cmFuc2l0aW9uIGZvciBhbGwgc3VyZmFjZXMuIEVhY2ggc3VyZmFjZSBjb3VsZCBoYXZlIGl0c1xuICogb3duIHRyYW5zaXRpb24uXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiA8Y29kZT5cbiAqIHN1cmZhY2Uuc2V0VHJhbnNpdGlvbkZuKGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gKiAgIGlmIChmcm9tKSB7XG4gKiAgICAgZnJvbS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICogICAgIGZyb20uY2xhc3NMaXN0LnJlbW92ZSgnZmxpcHBlZCcpO1xuICogICB9XG4gKiAgIGlmICh0bykge1xuICogICAgIHRvLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICogICAgIHRvLmNsYXNzTGlzdC5hZGQoJ2ZsaXBwZWQnKTtcbiAqICAgfVxuICogICByZXR1cm4gbnVsbDtcbiAqIH0pO1xuICogPC9jb2RlPlxuICpcbiAqIEBwYXJhbSB7P0VsZW1lbnQ9fSBmcm9tIFRoZSB2aXNpYmxlIHN1cmZhY2UgZWxlbWVudC5cbiAqIEBwYXJhbSB7P0VsZW1lbnQ9fSB0byBUaGUgc3VyZmFjZSBlbGVtZW50IHRvIGJlIGZsaXBwZWQuXG4gKiBAc3RhdGljXG4gKi9cblN1cmZhY2UuZGVmYXVsdFRyYW5zaXRpb24gPSBmdW5jdGlvbihmcm9tLCB0bykge1xuXHRpZiAoZnJvbSkge1xuXHRcdGZyb20uc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRmcm9tLmNsYXNzTGlzdC5yZW1vdmUoJ2ZsaXBwZWQnKTtcblx0fVxuXHRpZiAodG8pIHtcblx0XHR0by5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblx0XHR0by5jbGFzc0xpc3QuYWRkKCdmbGlwcGVkJyk7XG5cdH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFN1cmZhY2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGFkZENsYXNzZXMsIGRlbGVnYXRlLCBtYXRjaCwgb24sIHJlbW92ZUNsYXNzZXMgfSBmcm9tICdtZXRhbC1kb20nO1xuaW1wb3J0IHsgYXJyYXksIGFzeW5jLCBpc0RlZkFuZE5vdE51bGwsIGlzU3RyaW5nLCBvYmplY3QgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIsIEV2ZW50SGFuZGxlciB9IGZyb20gJ21ldGFsLWV2ZW50cyc7XG5pbXBvcnQgQ2FuY2VsbGFibGVQcm9taXNlIGZyb20gJ21ldGFsLXByb21pc2UnO1xuaW1wb3J0IGRlYm91bmNlIGZyb20gJ21ldGFsLWRlYm91bmNlJztcbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgUm91dGUgZnJvbSAnLi4vcm91dGUvUm91dGUnO1xuaW1wb3J0IFNjcmVlbiBmcm9tICcuLi9zY3JlZW4vU2NyZWVuJztcbmltcG9ydCBTdXJmYWNlIGZyb20gJy4uL3N1cmZhY2UvU3VyZmFjZSc7XG5pbXBvcnQgVXJpIGZyb20gJ21ldGFsLXVyaSc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi4vdXRpbHMvdXRpbHMnO1xuXG5jb25zdCBOYXZpZ2F0aW9uU3RyYXRlZ3kgPSB7XG5cdElNTUVESUFURTogJ2ltbWVkaWF0ZScsXG5cdFNDSEVEVUxFX0xBU1Q6ICdzY2hlZHVsZUxhc3QnXG59O1xuXG5jbGFzcyBBcHAgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuXG5cdC8qKlxuXHQgKiBBcHAgY2xhc3MgdGhhdCBoYW5kbGUgcm91dGVzIGFuZCBzY3JlZW5zIGxpZmVjeWNsZS5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqIEBleHRlbmRzIHtFdmVudEVtaXR0ZXJ9XG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGFjdGl2ZSBzY3JlZW4uXG5cdFx0ICogQHR5cGUgez9TY3JlZW59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYWN0aXZlU2NyZWVuID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBhY3RpdmUgcGF0aCBjb250YWluaW5nIHRoZSBxdWVyeSBwYXJhbWV0ZXJzLlxuXHRcdCAqIEB0eXBlIHs/c3RyaW5nfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmFjdGl2ZVBhdGggPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogQWxsb3dzIHByZXZlbnQgbmF2aWdhdGUgZnJvbSBkb20gcHJldmVudGVkIGV2ZW50LlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IHRydWVcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZSA9IHRydWU7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBsaW5rIGJhc2UgcGF0aC5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCAnJ1xuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmJhc2VQYXRoID0gJyc7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgdmFsdWUgb2YgdGhlIGJyb3dzZXIgcGF0aCBiZWZvcmUgYSBuYXZpZ2F0aW9uIGlzIHBlcmZvcm1lZC5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCB0aGUgY3VycmVudCBicm93c2VyIHBhdGguXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYnJvd3NlclBhdGhCZWZvcmVOYXZpZ2F0ZSA9IHV0aWxzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCk7XG5cblx0XHQvKipcblx0XHQgKiBDYXB0dXJlcyBzY3JvbGwgcG9zaXRpb24gZnJvbSBzY3JvbGwgZXZlbnQuXG5cdFx0ICogQHR5cGUgeyFib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IHRydWVcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5jYXB0dXJlU2Nyb2xsUG9zaXRpb25Gcm9tU2Nyb2xsRXZlbnQgPSB0cnVlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGRlZmF1bHQgcGFnZSB0aXRsZS5cblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5kZWZhdWx0VGl0bGUgPSBnbG9iYWxzLmRvY3VtZW50LnRpdGxlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGZvcm0gc2VsZWN0b3IgdG8gZGVmaW5lIGZvcm1zIHRoYXQgYXJlIHJvdXRlZC5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBmb3JtW2VuY3R5cGU9XCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJdOm5vdChbZGF0YS1zZW5uYS1vZmZdKVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmZvcm1TZWxlY3RvciA9ICdmb3JtW2VuY3R5cGU9XCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJdOm5vdChbZGF0YS1zZW5uYS1vZmZdKSc7XG5cblx0XHQvKipcblx0XHQgKiBXaGVuIGVuYWJsZWQsIHRoZSByb3V0ZSBtYXRjaGluZyBpZ25vcmVzIHF1ZXJ5IHN0cmluZyBmcm9tIHRoZSBwYXRoLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IGZhbHNlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoID0gZmFsc2U7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgbGluayBzZWxlY3RvciB0byBkZWZpbmUgbGlua3MgdGhhdCBhcmUgcm91dGVkLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IGE6bm90KFtkYXRhLXNlbm5hLW9mZl0pXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubGlua1NlbGVjdG9yID0gJ2E6bm90KFtkYXRhLXNlbm5hLW9mZl0pOm5vdChbdGFyZ2V0PVwiX2JsYW5rXCJdKSc7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgbG9hZGluZyBjc3MgY2xhc3MuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgc2VubmEtbG9hZGluZ1xuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmxvYWRpbmdDc3NDbGFzcyA9ICdzZW5uYS1sb2FkaW5nJztcblxuXHRcdC8qKlxuXHRcdCAqIFVzaW5nIHRoZSBIaXN0b3J5IEFQSSB0byBtYW5hZ2UgeW91ciBVUkxzIGlzIGF3ZXNvbWUgYW5kLCBhcyBpdCBoYXBwZW5zLFxuXHRcdCAqIGEgY3J1Y2lhbCBmZWF0dXJlIG9mIGdvb2Qgd2ViIGFwcHMuIE9uZSBvZiBpdHMgZG93bnNpZGVzLCBob3dldmVyLCBpc1xuXHRcdCAqIHRoYXQgc2Nyb2xsIHBvc2l0aW9ucyBhcmUgc3RvcmVkIGFuZCB0aGVuLCBtb3JlIGltcG9ydGFudGx5LCByZXN0b3JlZFxuXHRcdCAqIHdoZW5ldmVyIHlvdSB0cmF2ZXJzZSB0aGUgaGlzdG9yeS4gVGhpcyBvZnRlbiBtZWFucyB1bnNpZ2h0bHkganVtcHMgYXNcblx0XHQgKiB0aGUgc2Nyb2xsIHBvc2l0aW9uIGNoYW5nZXMgYXV0b21hdGljYWxseSwgYW5kIGVzcGVjaWFsbHkgc28gaWYgeW91ciBhcHBcblx0XHQgKiBkb2VzIHRyYW5zaXRpb25zLCBvciBjaGFuZ2VzIHRoZSBjb250ZW50cyBvZiB0aGUgcGFnZSBpbiBhbnkgd2F5LlxuXHRcdCAqIFVsdGltYXRlbHkgdGhpcyBsZWFkcyB0byBhbiBob3JyaWJsZSB1c2VyIGV4cGVyaWVuY2UuIFRoZSBnb29kIG5ld3MgaXMsXG5cdFx0ICogaG93ZXZlciwgdGhhdCB0aGVyZeKAmXMgYSBwb3RlbnRpYWwgZml4OiBoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uLlxuXHRcdCAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3dlYi91cGRhdGVzLzIwMTUvMDkvaGlzdG9yeS1hcGktc2Nyb2xsLXJlc3RvcmF0aW9uXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25TdXBwb3J0ZWQgPSAoJ3Njcm9sbFJlc3RvcmF0aW9uJyBpbiBnbG9iYWxzLndpbmRvdy5oaXN0b3J5KTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZW4gc2V0IHRvIE5hdmlnYXRpb25TdHJhdGVneS5TQ0hFRFVMRV9MQVNUIG1lYW5zIHRoYXQgdGhlIGN1cnJlbnQgbmF2aWdhdGlvblxuXHRcdCAqIGNhbm5vdCBiZSBDYW5jZWxsZWQgdG8gc3RhcnQgYW5vdGhlciBhbmQgd2lsbCBiZSBxdWV1ZWQgaW5cblx0XHQgKiBzY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUuIFdoZW4gTmF2aWdhdGlvblN0cmF0ZWd5LklNTUVESUFURSBtZWFucyB0aGF0IGFsbFxuXHRcdCAqIG5hdmlnYXRpb24gd2lsbCBiZSBjYW5jZWxsZWQgdG8gc3RhcnQgYW5vdGhlci5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBpbW1lZGlhdGVcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5uYXZpZ2F0aW9uU3RyYXRlZ3kgPSBOYXZpZ2F0aW9uU3RyYXRlZ3kuSU1NRURJQVRFO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBzZXQgdG8gdHJ1ZSB0aGVyZSBpcyBhIHBlbmRpbmdOYXZpZ2F0ZSB0aGF0IGhhcyBub3QgeWV0IGJlZW5cblx0XHQgKiByZXNvbHZlZCBvciByZWplY3RlZC5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCBmYWxzZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgPSBmYWxzZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGEgZGVmZXJyZWQgd2l0aCB0aGUgY3VycmVudCBuYXZpZ2F0aW9uLlxuXHRcdCAqIEB0eXBlIHs/Q2FuY2VsbGFibGVQcm9taXNlfVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHdpbmRvdyBob3Jpem9udGFsIHNjcm9sbCBwb3NpdGlvbiB3aGVuIHRoZSBuYXZpZ2F0aW9uIHVzaW5nXG5cdFx0ICogYmFjayBvciBmb3J3YXJkIGhhcHBlbnMgdG8gYmUgcmVzdG9yZWQgYWZ0ZXIgdGhlIHN1cmZhY2VzIGFyZSB1cGRhdGVkLlxuXHRcdCAqIEB0eXBlIHshTnVtYmVyfVxuXHRcdCAqIEBkZWZhdWx0IDBcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5wb3BzdGF0ZVNjcm9sbExlZnQgPSAwO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHdpbmRvdyB2ZXJ0aWNhbCBzY3JvbGwgcG9zaXRpb24gd2hlbiB0aGUgbmF2aWdhdGlvbiB1c2luZ1xuXHRcdCAqIGJhY2sgb3IgZm9yd2FyZCBoYXBwZW5zIHRvIGJlIHJlc3RvcmVkIGFmdGVyIHRoZSBzdXJmYWNlcyBhcmUgdXBkYXRlZC5cblx0XHQgKiBAdHlwZSB7IU51bWJlcn1cblx0XHQgKiBAZGVmYXVsdCAwXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucG9wc3RhdGVTY3JvbGxUb3AgPSAwO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHJlZGlyZWN0IHBhdGggY29udGFpbmluZyB0aGUgcXVlcnkgcGFyYW1ldGVycy5cblx0XHQgKiBAdHlwZSB7P3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5yZWRpcmVjdFBhdGggPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHNjcmVlbiByb3V0ZXMgY29uZmlndXJhdGlvbi5cblx0XHQgKiBAdHlwZSB7P0FycmF5fVxuXHRcdCAqIEBkZWZhdWx0IFtdXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucm91dGVzID0gW107XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBhIHF1ZXVlIHRoYXQgc3RvcmVzIGV2ZXJ5IERPTSBldmVudCB0aGF0IGNhbiBpbml0aWF0ZSBhIG5hdmlnYXRpb24uXG5cdFx0ICogQHR5cGUgeyFFdmVudH1cblx0XHQgKiBAZGVmYXVsdCBbXVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZSA9IFtdO1xuXG5cdFx0LyoqXG5cdFx0ICogTWFwcyB0aGUgc2NyZWVuIGluc3RhbmNlcyBieSB0aGUgdXJsIGNvbnRhaW5pbmcgdGhlIHBhcmFtZXRlcnMuXG5cdFx0ICogQHR5cGUgez9PYmplY3R9XG5cdFx0ICogQGRlZmF1bHQge31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zY3JlZW5zID0ge307XG5cblx0XHQvKipcblx0XHQgKiBXaGVuIHNldCB0byB0cnVlIHRoZSBmaXJzdCBlcnJvbmVvdXMgcG9wc3RhdGUgZmlyZWQgb24gcGFnZSBsb2FkIHdpbGwgYmVcblx0XHQgKiBpZ25vcmVkLCBvbmx5IGlmIDxjb2RlPmdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc3RhdGU8L2NvZGU+IGlzIGFsc29cblx0XHQgKiA8Y29kZT5udWxsPC9jb2RlPi5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCBmYWxzZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnNraXBMb2FkUG9wc3RhdGUgPSBmYWxzZTtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcHMgdGhhdCBpbmRleCB0aGUgc3VyZmFjZXMgaW5zdGFuY2VzIGJ5IHRoZSBzdXJmYWNlIGlkLlxuXHRcdCAqIEB0eXBlIHs/T2JqZWN0fVxuXHRcdCAqIEBkZWZhdWx0IHt9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuc3VyZmFjZXMgPSB7fTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZW4gc2V0IHRvIHRydWUsIG1vdmVzIHRoZSBzY3JvbGwgcG9zaXRpb24gYWZ0ZXIgcG9wc3RhdGUsIG9yIHRvIHRoZVxuXHRcdCAqIHRvcCBvZiB0aGUgdmlld3BvcnQgZm9yIG5ldyBuYXZpZ2F0aW9uLiBJZiBmYWxzZSwgdGhlIGJyb3dzZXIgd2lsbFxuXHRcdCAqIHRha2UgY2FyZSBvZiBzY3JvbGwgcmVzdG9yYXRpb24uXG5cdFx0ICogQHR5cGUgeyFib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IHRydWVcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy51cGRhdGVTY3JvbGxQb3NpdGlvbiA9IHRydWU7XG5cblx0XHR0aGlzLmFwcEV2ZW50SGFuZGxlcnNfID0gbmV3IEV2ZW50SGFuZGxlcigpO1xuXG5cdFx0dGhpcy5hcHBFdmVudEhhbmRsZXJzXy5hZGQoXG5cdFx0XHRvbihnbG9iYWxzLndpbmRvdywgJ3Njcm9sbCcsIGRlYm91bmNlKHRoaXMub25TY3JvbGxfLmJpbmQodGhpcyksIDEwMCkpLFxuXHRcdFx0b24oZ2xvYmFscy53aW5kb3csICdsb2FkJywgdGhpcy5vbkxvYWRfLmJpbmQodGhpcykpLFxuXHRcdFx0b24oZ2xvYmFscy53aW5kb3csICdwb3BzdGF0ZScsIHRoaXMub25Qb3BzdGF0ZV8uYmluZCh0aGlzKSlcblx0XHQpO1xuXG5cdFx0dGhpcy5vbignc3RhcnROYXZpZ2F0ZScsIHRoaXMub25TdGFydE5hdmlnYXRlXyk7XG5cdFx0dGhpcy5vbignYmVmb3JlTmF2aWdhdGUnLCB0aGlzLm9uQmVmb3JlTmF2aWdhdGVfKTtcblx0XHR0aGlzLm9uKCdiZWZvcmVOYXZpZ2F0ZScsIHRoaXMub25CZWZvcmVOYXZpZ2F0ZURlZmF1bHRfLCB0cnVlKTtcblx0XHR0aGlzLm9uKCdiZWZvcmVVbmxvYWQnLCB0aGlzLm9uQmVmb3JlVW5sb2FkRGVmYXVsdF8pO1xuXG5cdFx0dGhpcy5zZXRMaW5rU2VsZWN0b3IodGhpcy5saW5rU2VsZWN0b3IpO1xuXHRcdHRoaXMuc2V0Rm9ybVNlbGVjdG9yKHRoaXMuZm9ybVNlbGVjdG9yKTtcblxuXHRcdHRoaXMubWF5YmVPdmVybG9hZEJlZm9yZVVubG9hZF8oKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIG9uZSBvciBtb3JlIHNjcmVlbnMgdG8gdGhlIGFwcGxpY2F0aW9uLlxuXHQgKlxuXHQgKiBFeGFtcGxlOlxuXHQgKlxuXHQgKiA8Y29kZT5cblx0ICogICBhcHAuYWRkUm91dGVzKHsgcGF0aDogJy9mb28nLCBoYW5kbGVyOiBGb29TY3JlZW4gfSk7XG5cdCAqICAgb3Jcblx0ICogICBhcHAuYWRkUm91dGVzKFt7IHBhdGg6ICcvZm9vJywgaGFuZGxlcjogZnVuY3Rpb24ocm91dGUpIHsgcmV0dXJuIG5ldyBGb29TY3JlZW4oKTsgfSB9XSk7XG5cdCAqIDwvY29kZT5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9yIHtBcnJheX0gcm91dGVzIFNpbmdsZSBvYmplY3Qgb3IgYW4gYXJyYXkgb2Ygb2JqZWN0LlxuXHQgKiAgICAgRWFjaCBvYmplY3Qgc2hvdWxkIGNvbnRhaW4gPGNvZGU+cGF0aDwvY29kZT4gYW5kIDxjb2RlPnNjcmVlbjwvY29kZT4uXG5cdCAqICAgICBUaGUgPGNvZGU+cGF0aDwvY29kZT4gc2hvdWxkIGJlIGEgc3RyaW5nIG9yIGEgcmVnZXggdGhhdCBtYXBzIHRoZVxuXHQgKiAgICAgbmF2aWdhdGlvbiByb3V0ZSB0byBhIHNjcmVlbiBjbGFzcyBkZWZpbml0aW9uIChub3QgYW4gaW5zdGFuY2UpLCBlLmc6XG5cdCAqICAgICAgICAgPGNvZGU+eyBwYXRoOiBcIi9ob21lOnBhcmFtMVwiLCBoYW5kbGVyOiBNeVNjcmVlbiB9PC9jb2RlPlxuXHQgKiAgICAgICAgIDxjb2RlPnsgcGF0aDogL2Zvby4rLywgaGFuZGxlcjogTXlTY3JlZW4gfTwvY29kZT5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkUm91dGVzKHJvdXRlcykge1xuXHRcdGlmICghQXJyYXkuaXNBcnJheShyb3V0ZXMpKSB7XG5cdFx0XHRyb3V0ZXMgPSBbcm91dGVzXTtcblx0XHR9XG5cdFx0cm91dGVzLmZvckVhY2goKHJvdXRlKSA9PiB7XG5cdFx0XHRpZiAoIShyb3V0ZSBpbnN0YW5jZW9mIFJvdXRlKSkge1xuXHRcdFx0XHRyb3V0ZSA9IG5ldyBSb3V0ZShyb3V0ZS5wYXRoLCByb3V0ZS5oYW5kbGVyKTtcblx0XHRcdH1cblx0XHRcdHRoaXMucm91dGVzLnB1c2gocm91dGUpO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgb25lIG9yIG1vcmUgc3VyZmFjZXMgdG8gdGhlIGFwcGxpY2F0aW9uLlxuXHQgKiBAcGFyYW0ge1N1cmZhY2V8U3RyaW5nfEFycmF5LjxTdXJmYWNlfFN0cmluZz59IHN1cmZhY2VzXG5cdCAqICAgICBTdXJmYWNlIGVsZW1lbnQgaWQgb3Igc3VyZmFjZSBpbnN0YW5jZS4gWW91IGNhbiBhbHNvIHBhc3MgYW4gQXJyYXlcblx0ICogICAgIHdoaWNoY29udGFpbnMgc3VyZmFjZSBpbnN0YW5jZXMgb3IgaWQuIEluIGNhc2Ugb2YgSUQsIHRoZXNlIHNob3VsZCBiZVxuXHQgKiAgICAgdGhlIGlkIG9mIHN1cmZhY2UgZWxlbWVudC5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkU3VyZmFjZXMoc3VyZmFjZXMpIHtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkoc3VyZmFjZXMpKSB7XG5cdFx0XHRzdXJmYWNlcyA9IFtzdXJmYWNlc107XG5cdFx0fVxuXHRcdHN1cmZhY2VzLmZvckVhY2goKHN1cmZhY2UpID0+IHtcblx0XHRcdGlmIChpc1N0cmluZyhzdXJmYWNlKSkge1xuXHRcdFx0XHRzdXJmYWNlID0gbmV3IFN1cmZhY2Uoc3VyZmFjZSk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnN1cmZhY2VzW3N1cmZhY2UuZ2V0SWQoKV0gPSBzdXJmYWNlO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgaWYgY2FuIG5hdmlnYXRlIHRvIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gdXJsXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRjYW5OYXZpZ2F0ZSh1cmwpIHtcblx0XHRjb25zdCB1cmkgPSB1dGlscy5pc1dlYlVyaSh1cmwpO1xuXG5cdFx0aWYgKCF1cmkpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRjb25zdCBwYXRoID0gdXRpbHMuZ2V0VXJsUGF0aCh1cmwpO1xuXG5cdFx0aWYgKCF0aGlzLmlzTGlua1NhbWVPcmlnaW5fKHVyaS5nZXRIb3N0KCkpKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnT2Zmc2l0ZSBsaW5rIGNsaWNrZWQnKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCF0aGlzLmlzU2FtZUJhc2VQYXRoXyhwYXRoKSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ0xpbmsgY2xpY2tlZCBvdXRzaWRlIGFwcFxcJ3MgYmFzZSBwYXRoJyk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdC8vIFByZXZlbnRzIG5hdmlnYXRpb24gaWYgaXQncyBhIGhhc2ggY2hhbmdlIG9uIHRoZSBzYW1lIHVybC5cblx0XHRpZiAodXJpLmdldEhhc2goKSAmJiB1dGlscy5pc0N1cnJlbnRCcm93c2VyUGF0aChwYXRoKSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAoIXRoaXMuZmluZFJvdXRlKHBhdGgpKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnTm8gcm91dGUgZm9yICcgKyBwYXRoKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhciBzY3JlZW5zIGNhY2hlLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRjbGVhclNjcmVlbnNDYWNoZSgpIHtcblx0XHRPYmplY3Qua2V5cyh0aGlzLnNjcmVlbnMpLmZvckVhY2goKHBhdGgpID0+IHtcblx0XHRcdGlmIChwYXRoID09PSB0aGlzLmFjdGl2ZVBhdGgpIHtcblx0XHRcdFx0dGhpcy5hY3RpdmVTY3JlZW4uY2xlYXJDYWNoZSgpO1xuXHRcdFx0fSBlbHNlIGlmICghKHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyAmJiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZS5wYXRoID09PSBwYXRoKSkge1xuXHRcdFx0XHR0aGlzLnJlbW92ZVNjcmVlbihwYXRoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXRyaWV2ZXMgb3IgY3JlYXRlIGEgc2NyZWVuIGluc3RhbmNlIHRvIGEgcGF0aC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHJldHVybiB7U2NyZWVufVxuXHQgKi9cblx0Y3JlYXRlU2NyZWVuSW5zdGFuY2UocGF0aCwgcm91dGUpIHtcblx0XHRpZiAoIXRoaXMucGVuZGluZ05hdmlnYXRlICYmIHBhdGggPT09IHRoaXMuYWN0aXZlUGF0aCkge1xuXHRcdFx0Y29uc29sZS5sb2coJ0FscmVhZHkgYXQgZGVzdGluYXRpb24sIHJlZnJlc2ggbmF2aWdhdGlvbicpO1xuXHRcdFx0cmV0dXJuIHRoaXMuYWN0aXZlU2NyZWVuO1xuXHRcdH1cblx0XHQvKiBqc2hpbnQgbmV3Y2FwOiBmYWxzZSAqL1xuXHRcdHZhciBzY3JlZW4gPSB0aGlzLnNjcmVlbnNbcGF0aF07XG5cdFx0aWYgKCFzY3JlZW4pIHtcblx0XHRcdHZhciBoYW5kbGVyID0gcm91dGUuZ2V0SGFuZGxlcigpO1xuXHRcdFx0aWYgKGhhbmRsZXIgPT09IFNjcmVlbiB8fCBTY3JlZW4uaXNJbXBsZW1lbnRlZEJ5KGhhbmRsZXIucHJvdG90eXBlKSkge1xuXHRcdFx0XHRzY3JlZW4gPSBuZXcgaGFuZGxlcigpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c2NyZWVuID0gaGFuZGxlcihyb3V0ZSkgfHwgbmV3IFNjcmVlbigpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc29sZS5sb2coJ0NyZWF0ZSBzY3JlZW4gZm9yIFsnICsgcGF0aCArICddIFsnICsgc2NyZWVuICsgJ10nKTtcblx0XHR9XG5cdFx0cmV0dXJuIHNjcmVlbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdGlmICh0aGlzLmFjdGl2ZVNjcmVlbikge1xuXHRcdFx0dGhpcy5yZW1vdmVTY3JlZW4odGhpcy5hY3RpdmVQYXRoKTtcblx0XHR9XG5cdFx0dGhpcy5jbGVhclNjcmVlbnNDYWNoZSgpO1xuXHRcdHRoaXMuZm9ybUV2ZW50SGFuZGxlcl8ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR0aGlzLmxpbmtFdmVudEhhbmRsZXJfLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0dGhpcy5hcHBFdmVudEhhbmRsZXJzXy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblx0XHRzdXBlci5kaXNwb3NlSW50ZXJuYWwoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwYXRjaGVzIHRvIHRoZSBmaXJzdCByb3V0ZSBoYW5kbGVyIHRoYXQgbWF0Y2hlcyB0aGUgY3VycmVudCBwYXRoLCBpZlxuXHQgKiBhbnkuXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUmV0dXJucyBhIHBlbmRpbmcgcmVxdWVzdCBjYW5jZWxsYWJsZSBwcm9taXNlLlxuXHQgKi9cblx0ZGlzcGF0Y2goKSB7XG5cdFx0cmV0dXJuIHRoaXMubmF2aWdhdGUodXRpbHMuZ2V0Q3VycmVudEJyb3dzZXJQYXRoKCksIHRydWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFN0YXJ0cyBuYXZpZ2F0aW9uIHRvIGEgcGF0aC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JlcGxhY2VIaXN0b3J5IFJlcGxhY2VzIGJyb3dzZXIgaGlzdG9yeS5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfSBSZXR1cm5zIGEgcGVuZGluZyByZXF1ZXN0IGNhbmNlbGxhYmxlIHByb21pc2UuXG5cdCAqL1xuXHRkb05hdmlnYXRlXyhwYXRoLCBvcHRfcmVwbGFjZUhpc3RvcnkpIHtcblx0XHR2YXIgcm91dGUgPSB0aGlzLmZpbmRSb3V0ZShwYXRoKTtcblx0XHRpZiAoIXJvdXRlKSB7XG5cdFx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IENhbmNlbGxhYmxlUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxhYmxlUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvcignTm8gcm91dGUgZm9yICcgKyBwYXRoKSk7XG5cdFx0XHRyZXR1cm4gdGhpcy5wZW5kaW5nTmF2aWdhdGU7XG5cdFx0fVxuXG5cdFx0Y29uc29sZS5sb2coJ05hdmlnYXRlIHRvIFsnICsgcGF0aCArICddJyk7XG5cblx0XHR0aGlzLnN0b3BQZW5kaW5nTmF2aWdhdGVfKCk7XG5cdFx0dGhpcy5pc05hdmlnYXRpb25QZW5kaW5nID0gdHJ1ZTtcblxuXHRcdHZhciBuZXh0U2NyZWVuID0gdGhpcy5jcmVhdGVTY3JlZW5JbnN0YW5jZShwYXRoLCByb3V0ZSk7XG5cblx0XHRyZXR1cm4gdGhpcy5tYXliZVByZXZlbnREZWFjdGl2YXRlXygpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLm1heWJlUHJldmVudEFjdGl2YXRlXyhuZXh0U2NyZWVuKSlcblx0XHRcdC50aGVuKCgpID0+IG5leHRTY3JlZW4ubG9hZChwYXRoKSlcblx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0Ly8gQXQgdGhpcyBwb2ludCB3ZSBjYW5ub3Qgc3RvcCBuYXZpZ2F0aW9uIGFuZCBhbGwgcmVjZWl2ZWRcblx0XHRcdFx0Ly8gbmF2aWdhdGUgY2FuZGlkYXRlcyB3aWxsIGJlIHF1ZXVlZCBhdCBzY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUuXG5cdFx0XHRcdHRoaXMubmF2aWdhdGlvblN0cmF0ZWd5ID0gTmF2aWdhdGlvblN0cmF0ZWd5LlNDSEVEVUxFX0xBU1Q7XG5cblx0XHRcdFx0aWYgKHRoaXMuYWN0aXZlU2NyZWVuKSB7XG5cdFx0XHRcdFx0dGhpcy5hY3RpdmVTY3JlZW4uZGVhY3RpdmF0ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMucHJlcGFyZU5hdmlnYXRlSGlzdG9yeV8ocGF0aCwgbmV4dFNjcmVlbiwgb3B0X3JlcGxhY2VIaXN0b3J5KTtcblx0XHRcdFx0dGhpcy5wcmVwYXJlTmF2aWdhdGVTdXJmYWNlc18oXG5cdFx0XHRcdFx0bmV4dFNjcmVlbixcblx0XHRcdFx0XHR0aGlzLnN1cmZhY2VzLFxuXHRcdFx0XHRcdHRoaXMuZXh0cmFjdFBhcmFtcyhyb3V0ZSwgcGF0aClcblx0XHRcdFx0KTtcblx0XHRcdH0pXG5cdFx0XHQudGhlbigoKSA9PiBuZXh0U2NyZWVuLmV2YWx1YXRlU3R5bGVzKHRoaXMuc3VyZmFjZXMpKVxuXHRcdFx0LnRoZW4oKCkgPT4gbmV4dFNjcmVlbi5mbGlwKHRoaXMuc3VyZmFjZXMpKVxuXHRcdFx0LnRoZW4oKCkgPT4gbmV4dFNjcmVlbi5ldmFsdWF0ZVNjcmlwdHModGhpcy5zdXJmYWNlcykpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLm1heWJlVXBkYXRlU2Nyb2xsUG9zaXRpb25TdGF0ZV8oKSlcblx0XHRcdC50aGVuKCgpID0+IHRoaXMuc3luY1Njcm9sbFBvc2l0aW9uU3luY1RoZW5Bc3luY18oKSlcblx0XHRcdC50aGVuKCgpID0+IHRoaXMuZmluYWxpemVOYXZpZ2F0ZV8ocGF0aCwgbmV4dFNjcmVlbikpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLm1heWJlT3ZlcmxvYWRCZWZvcmVVbmxvYWRfKCkpXG5cdFx0XHQuY2F0Y2goKHJlYXNvbikgPT4ge1xuXHRcdFx0XHR0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgPSBmYWxzZTtcblx0XHRcdFx0dGhpcy5oYW5kbGVOYXZpZ2F0ZUVycm9yXyhwYXRoLCBuZXh0U2NyZWVuLCByZWFzb24pO1xuXHRcdFx0XHR0aHJvdyByZWFzb247XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW5BbHdheXMoKCkgPT4ge1xuXHRcdFx0XHR0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9IE5hdmlnYXRpb25TdHJhdGVneS5JTU1FRElBVEU7XG5cblx0XHRcdFx0aWYgKHRoaXMuc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLmxlbmd0aCkge1xuXHRcdFx0XHRcdGNvbnN0IHNjaGVkdWxlZE5hdmlnYXRpb24gPSB0aGlzLnNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZS5zaGlmdCgpO1xuXHRcdFx0XHRcdHRoaXMubWF5YmVOYXZpZ2F0ZV8oc2NoZWR1bGVkTmF2aWdhdGlvbi5ocmVmLCBzY2hlZHVsZWROYXZpZ2F0aW9uKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgcGFyYW1zIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gcGF0aCBhbmQgcm91dGUuXG5cdCAqIEBwYXJhbSB7IVJvdXRlfSByb3V0ZVxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuXHQgKiBAcGFyYW0geyFPYmplY3R9XG5cdCAqL1xuXHRleHRyYWN0UGFyYW1zKHJvdXRlLCBwYXRoKSB7XG5cdFx0cmV0dXJuIHJvdXRlLmV4dHJhY3RQYXJhbXModGhpcy5nZXRSb3V0ZVBhdGgocGF0aCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEZpbmFsaXplcyBhIHNjcmVlbiBuYXZpZ2F0aW9uLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcGFyYW0geyFTY3JlZW59IG5leHRTY3JlZW5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0ZmluYWxpemVOYXZpZ2F0ZV8ocGF0aCwgbmV4dFNjcmVlbikge1xuXHRcdG5leHRTY3JlZW4uYWN0aXZhdGUoKTtcblxuXHRcdGlmICh0aGlzLmFjdGl2ZVNjcmVlbiAmJiAhdGhpcy5hY3RpdmVTY3JlZW4uaXNDYWNoZWFibGUoKSkge1xuXHRcdFx0aWYgKHRoaXMuYWN0aXZlU2NyZWVuICE9PSBuZXh0U2NyZWVuKSB7XG5cdFx0XHRcdHRoaXMucmVtb3ZlU2NyZWVuKHRoaXMuYWN0aXZlUGF0aCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5hY3RpdmVQYXRoID0gcGF0aDtcblx0XHR0aGlzLmFjdGl2ZVNjcmVlbiA9IG5leHRTY3JlZW47XG5cdFx0dGhpcy5icm93c2VyUGF0aEJlZm9yZU5hdmlnYXRlID0gdXRpbHMuZ2V0Q3VycmVudEJyb3dzZXJQYXRoV2l0aG91dEhhc2goKTtcblx0XHR0aGlzLnNjcmVlbnNbcGF0aF0gPSBuZXh0U2NyZWVuO1xuXHRcdHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyA9IGZhbHNlO1xuXHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gbnVsbDtcblx0XHRnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQgPSBudWxsO1xuXHRcdGdsb2JhbHMuY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudCA9IG51bGw7XG5cdFx0Y29uc29sZS5sb2coJ05hdmlnYXRpb24gZG9uZScpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEZpbmRzIGEgcm91dGUgZm9yIHRoZSB0ZXN0IHBhdGguIFJldHVybnMgdHJ1ZSBpZiBtYXRjaGVzIGhhcyBhIHJvdXRlLFxuXHQgKiBvdGhlcndpc2UgcmV0dXJucyBudWxsLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcmV0dXJuIHs/T2JqZWN0fSBSb3V0ZSBoYW5kbGVyIGlmIG1hdGNoIGFueSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVcblx0ICogICAgIHBhdGggaXMgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnQgdXJsIGFuZCB0aGUgcGF0aCBjb250YWlucyBhIGZyYWdtZW50LlxuXHQgKi9cblx0ZmluZFJvdXRlKHBhdGgpIHtcblx0XHRwYXRoID0gdGhpcy5nZXRSb3V0ZVBhdGgocGF0aCk7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJvdXRlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIHJvdXRlID0gdGhpcy5yb3V0ZXNbaV07XG5cdFx0XHRpZiAocm91dGUubWF0Y2hlc1BhdGgocGF0aCkpIHtcblx0XHRcdFx0cmV0dXJuIHJvdXRlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYWxsb3cgcHJldmVudCBuYXZpZ2F0ZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGdldEFsbG93UHJldmVudE5hdmlnYXRlKCkge1xuXHRcdHJldHVybiB0aGlzLmFsbG93UHJldmVudE5hdmlnYXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgbGluayBiYXNlIHBhdGguXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRCYXNlUGF0aCgpIHtcblx0XHRyZXR1cm4gdGhpcy5iYXNlUGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBkZWZhdWx0IHBhZ2UgdGl0bGUuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gZGVmYXVsdFRpdGxlXG5cdCAqL1xuXHRnZXREZWZhdWx0VGl0bGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZGVmYXVsdFRpdGxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGZvcm0gc2VsZWN0b3IuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRGb3JtU2VsZWN0b3IoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZm9ybVNlbGVjdG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrIGlmIHJvdXRlIG1hdGNoaW5nIGlzIGlnbm9yaW5nIHF1ZXJ5IHN0cmluZyBmcm9tIHRoZSByb3V0ZSBwYXRoLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Z2V0SWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoKCkge1xuXHRcdHJldHVybiB0aGlzLmlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBsaW5rIHNlbGVjdG9yLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0TGlua1NlbGVjdG9yKCkge1xuXHRcdHJldHVybiB0aGlzLmxpbmtTZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBsb2FkaW5nIGNzcyBjbGFzcy5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldExvYWRpbmdDc3NDbGFzcygpIHtcblx0XHRyZXR1cm4gdGhpcy5sb2FkaW5nQ3NzQ2xhc3M7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgZ2l2ZW4gcGF0aCBmb3JtYXR0ZWQgdG8gYmUgbWF0Y2hlZCBieSBhIHJvdXRlLiBUaGlzIHdpbGwsXG5cdCAqIGZvciBleGFtcGxlLCByZW1vdmUgdGhlIGJhc2UgcGF0aCBmcm9tIGl0LCBidXQgbWFrZSBzdXJlIGl0IHdpbGwgZW5kXG5cdCAqIHdpdGggYSAnLycuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldFJvdXRlUGF0aChwYXRoKSB7XG5cdFx0aWYgKHRoaXMuZ2V0SWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoKCkpIHtcblx0XHRcdHBhdGggPSB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2hBbmRTZWFyY2gocGF0aCk7XG5cdFx0XHRyZXR1cm4gdXRpbHMuZ2V0VXJsUGF0aFdpdGhvdXRIYXNoQW5kU2VhcmNoKHBhdGguc3Vic3RyKHRoaXMuYmFzZVBhdGgubGVuZ3RoKSk7XG5cdFx0fVxuXG5cdFx0cGF0aCA9IHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaChwYXRoKTtcblx0XHRyZXR1cm4gdXRpbHMuZ2V0VXJsUGF0aFdpdGhvdXRIYXNoKHBhdGguc3Vic3RyKHRoaXMuYmFzZVBhdGgubGVuZ3RoKSk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgdXBkYXRlIHNjcm9sbCBwb3NpdGlvbiB2YWx1ZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGdldFVwZGF0ZVNjcm9sbFBvc2l0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnVwZGF0ZVNjcm9sbFBvc2l0aW9uO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhhbmRsZSBuYXZpZ2F0aW9uIGVycm9yLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcGFyYW0geyFTY3JlZW59IG5leHRTY3JlZW5cblx0ICogQHBhcmFtIHshRXJyb3J9IGVycm9yXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGhhbmRsZU5hdmlnYXRlRXJyb3JfKHBhdGgsIG5leHRTY3JlZW4sIGVycm9yKSB7XG5cdFx0Y29uc29sZS5sb2coJ05hdmlnYXRpb24gZXJyb3IgZm9yIFsnICsgbmV4dFNjcmVlbiArICddICgnICsgZXJyb3Iuc3RhY2sgKyAnKScpO1xuXHRcdHRoaXMuZW1pdCgnbmF2aWdhdGlvbkVycm9yJywge1xuXHRcdFx0ZXJyb3IsXG5cdFx0XHRuZXh0U2NyZWVuLFxuXHRcdFx0cGF0aFxuXHRcdH0pO1xuXHRcdGlmICghdXRpbHMuaXNDdXJyZW50QnJvd3NlclBhdGgocGF0aCkpIHtcblx0XHRcdGlmICh0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgJiYgdGhpcy5wZW5kaW5nTmF2aWdhdGUpIHtcblx0XHRcdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUudGhlbkFsd2F5cygoKSA9PiB0aGlzLnJlbW92ZVNjcmVlbihwYXRoKSwgdGhpcyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnJlbW92ZVNjcmVlbihwYXRoKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGFwcCBoYXMgcm91dGVzLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0aGFzUm91dGVzKCkge1xuXHRcdHJldHVybiB0aGlzLnJvdXRlcy5sZW5ndGggPiAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIGlmIGhvc3QgaXMgYW4gb2Zmc2l0ZSBsaW5rLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGhvc3QgTGluayBob3N0IHRvIGNvbXBhcmUgd2l0aFxuXHQgKiAgICAgPGNvZGU+Z2xvYmFscy53aW5kb3cubG9jYXRpb24uaG9zdDwvY29kZT4uXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGlzTGlua1NhbWVPcmlnaW5fKGhvc3QpIHtcblx0XHRjb25zdCBob3N0VXJpID0gbmV3IFVyaShob3N0KTtcblx0XHRjb25zdCBsb2NhdGlvbkhvc3RVcmkgPSBuZXcgVXJpKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhvc3QpO1xuXG5cdFx0cmV0dXJuIGhvc3RVcmkuZ2V0UG9ydCgpID09PSBsb2NhdGlvbkhvc3RVcmkuZ2V0UG9ydCgpICYmIGhvc3RVcmkuZ2V0SG9zdG5hbWUoKSA9PT0gbG9jYXRpb25Ib3N0VXJpLmdldEhvc3RuYW1lKCk7XG5cdH1cblxuXHQvKipcblx0ICogVGVzdHMgaWYgbGluayBlbGVtZW50IGhhcyB0aGUgc2FtZSBhcHAncyBiYXNlIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBMaW5rIHBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0aXNTYW1lQmFzZVBhdGhfKHBhdGgpIHtcblx0XHRyZXR1cm4gcGF0aC5pbmRleE9mKHRoaXMuYmFzZVBhdGgpID09PSAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIExvY2sgdGhlIGRvY3VtZW50IHNjcm9sbCBpbiBvcmRlciB0byBhdm9pZCB0aGUgYnJvd3NlciBuYXRpdmUgYmFjayBhbmRcblx0ICogZm9yd2FyZCBuYXZpZ2F0aW9uIHRvIGNoYW5nZSB0aGUgc2Nyb2xsIHBvc2l0aW9uLiBJbiB0aGUgZW5kIG9mXG5cdCAqIG5hdmlnYXRpb24gbGlmZWN5Y2xlIHNjcm9sbCBpcyByZXBvc2l0aW9uZWQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGxvY2tIaXN0b3J5U2Nyb2xsUG9zaXRpb25fKCkge1xuXHRcdHZhciBzdGF0ZSA9IGdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc3RhdGU7XG5cdFx0aWYgKCFzdGF0ZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHQvLyBCcm93c2VycyBhcmUgaW5jb25zaXN0ZW50IHdoZW4gcmUtcG9zaXRpb25pbmcgdGhlIHNjcm9sbCBoaXN0b3J5IG9uXG5cdFx0Ly8gcG9wc3RhdGUuIEF0IHNvbWUgYnJvd3NlcnMsIGhpc3Rvcnkgc2Nyb2xsIGhhcHBlbnMgYmVmb3JlIHBvcHN0YXRlLCB0aGVuXG5cdFx0Ly8gbG9jayB0aGUgc2Nyb2xsIG9uIHRoZSBsYXN0IGtub3duIHBvc2l0aW9uIGFzIHNvb24gYXMgcG9zc2libGUgYWZ0ZXIgdGhlXG5cdFx0Ly8gY3VycmVudCBKUyBleGVjdXRpb24gY29udGV4dCBhbmQgY2FwdHVyZSB0aGUgY3VycmVudCB2YWx1ZS4gU29tZSBvdGhlcnMsXG5cdFx0Ly8gaGlzdG9yeSBzY3JvbGwgaGFwcGVucyBhZnRlciBwb3BzdGF0ZSwgaW4gdGhpcyBjYXNlLCB3ZSBiaW5kIGFuIG9uY2Vcblx0XHQvLyBzY3JvbGwgZXZlbnQgdG8gbG9jayB0aGUgbGFzIGtub3duIHBvc2l0aW9uLiBMYXN0bHksIHRoZSBwcmV2aW91cyB0d29cblx0XHQvLyBiZWhhdmlvcnMgY2FuIGhhcHBlbiBldmVuIG9uIHRoZSBzYW1lIGJyb3dzZXIsIGhlbmNlIHRoZSByYWNlIHdpbGwgZGVjaWRlXG5cdFx0Ly8gdGhlIHdpbm5lci5cblx0XHR2YXIgd2lubmVyID0gZmFsc2U7XG5cdFx0dmFyIHN3aXRjaFNjcm9sbFBvc2l0aW9uUmFjZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0Z2xvYmFscy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBzd2l0Y2hTY3JvbGxQb3NpdGlvblJhY2UsIGZhbHNlKTtcblx0XHRcdGlmICghd2lubmVyKSB7XG5cdFx0XHRcdGdsb2JhbHMud2luZG93LnNjcm9sbFRvKHN0YXRlLnNjcm9sbExlZnQsIHN0YXRlLnNjcm9sbFRvcCk7XG5cdFx0XHRcdHdpbm5lciA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHRhc3luYy5uZXh0VGljayhzd2l0Y2hTY3JvbGxQb3NpdGlvblJhY2UpO1xuXHRcdGdsb2JhbHMuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgc3dpdGNoU2Nyb2xsUG9zaXRpb25SYWNlLCBmYWxzZSk7XG5cdH1cblxuXHQvKipcblx0ICogSWYgc3VwcG9ydGVkIGJ5IHRoZSBicm93c2VyLCBkaXNhYmxlcyBuYXRpdmUgc2Nyb2xsIHJlc3RvcmF0aW9uIGFuZFxuXHQgKiBzdG9yZXMgY3VycmVudCB2YWx1ZS5cblx0ICovXG5cdG1heWJlRGlzYWJsZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uKCkge1xuXHRcdGlmICh0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uU3VwcG9ydGVkKSB7XG5cdFx0XHR0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uXyA9IGdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb247XG5cdFx0XHRnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uID0gJ21hbnVhbCc7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gZXZhbHVhdGUgaWYgaXMgcG9zc2libGUgdG8gcXVldWUgcmVjZWl2ZWRcblx0ICogIGRvbSBldmVudCB0byBzY2hlZHVsZU5hdmlnYXRpb25RdWV1ZSBhbmQgZW5xdWV1ZSBpdC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgSW5mb3JtYXRpb24gYWJvdXQgdGhlIGxpbmsncyBocmVmLlxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudCBEb20gZXZlbnQgdGhhdCBpbml0aWF0ZWQgdGhlIG5hdmlnYXRpb24uXG5cdCAqL1xuXHRtYXliZVNjaGVkdWxlTmF2aWdhdGlvbl8oaHJlZiwgZXZlbnQpIHtcblx0XHRpZiAodGhpcy5pc05hdmlnYXRpb25QZW5kaW5nICYmIHRoaXMubmF2aWdhdGlvblN0cmF0ZWd5ID09PSBOYXZpZ2F0aW9uU3RyYXRlZ3kuU0NIRURVTEVfTEFTVCkge1xuXHRcdFx0dGhpcy5zY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUgPSBbb2JqZWN0Lm1peGluKHtcblx0XHRcdFx0aHJlZixcblx0XHRcdFx0aXNTY2hlZHVsZWROYXZpZ2F0aW9uOiB0cnVlXG5cdFx0XHR9LCBldmVudCldO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBuYXZpZ2F0ZSB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIEluZm9ybWF0aW9uIGFib3V0IHRoZSBsaW5rJ3MgaHJlZi5cblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnQgRG9tIGV2ZW50IHRoYXQgaW5pdGlhdGVkIHRoZSBuYXZpZ2F0aW9uLlxuXHQgKi9cblx0bWF5YmVOYXZpZ2F0ZV8oaHJlZiwgZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMuY2FuTmF2aWdhdGUoaHJlZikpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBpc05hdmlnYXRpb25TY2hlZHVsZWQgPSB0aGlzLm1heWJlU2NoZWR1bGVOYXZpZ2F0aW9uXyhocmVmLCBldmVudCk7XG5cblx0XHRpZiAoaXNOYXZpZ2F0aW9uU2NoZWR1bGVkKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBuYXZpZ2F0ZUZhaWxlZCA9IGZhbHNlO1xuXHRcdHRyeSB7XG5cdFx0XHR0aGlzLm5hdmlnYXRlKHV0aWxzLmdldFVybFBhdGgoaHJlZiksIGZhbHNlLCBldmVudCk7XG5cdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHQvLyBEbyBub3QgcHJldmVudCBsaW5rIG5hdmlnYXRpb24gaW4gY2FzZSBzb21lIHN5bmNocm9ub3VzIGVycm9yIG9jY3Vyc1xuXHRcdFx0bmF2aWdhdGVGYWlsZWQgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICghbmF2aWdhdGVGYWlsZWQgJiYgIWV2ZW50LmlzU2NoZWR1bGVkTmF2aWdhdGlvbikge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIHdoZXRoZXIgdGhlIG9uYmVmb3JldW5sb2FkIGdsb2JhbCBldmVudCBoYW5kbGVyIGlzIG92ZXJsb2FkZWRcblx0ICogYnkgY2xpZW50IGNvZGUuIElmIHNvLCBpdCByZXBsYWNlcyB3aXRoIGEgZnVuY3Rpb24gdGhhdCBoYWx0cyB0aGUgbm9ybWFsXG5cdCAqIGV2ZW50IGZsb3cgaW4gcmVsYXRpb24gd2l0aCB0aGUgY2xpZW50IG9uYmVmb3JldW5sb2FkIGZ1bmN0aW9uLlxuXHQgKiBUaGlzIGNhbiBiZSBpbiBtb3N0IHBhcnQgdXNlZCB0byBwcmVtYXR1cmVseSB0ZXJtaW5hdGUgbmF2aWdhdGlvbiB0byBvdGhlciBwYWdlc1xuXHQgKiBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGNvbnN0cmFpdChzKS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0bWF5YmVPdmVybG9hZEJlZm9yZVVubG9hZF8oKSB7XG5cdFx0aWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiB3aW5kb3cub25iZWZvcmV1bmxvYWQpIHtcblx0XHRcdHdpbmRvdy5fb25iZWZvcmV1bmxvYWQgPSB3aW5kb3cub25iZWZvcmV1bmxvYWQ7XG5cblx0XHRcdHdpbmRvdy5vbmJlZm9yZXVubG9hZCA9IGV2ZW50ID0+IHtcblx0XHRcdFx0dGhpcy5lbWl0KCdiZWZvcmVVbmxvYWQnLCBldmVudCk7XG5cdFx0XHRcdGlmIChldmVudCAmJiBldmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRcdC8vIG1hcmsgdGhlIHVwZGF0ZWQgaGFuZGxlciBkdWUgdW53YW50ZWQgcmVjdXJzaW9uXG5cdFx0XHR3aW5kb3cub25iZWZvcmV1bmxvYWQuX292ZXJsb2FkZWQgPSB0cnVlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDYW5jZWxzIG5hdmlnYXRpb24gaWYgbmV4dFNjcmVlbidzIGJlZm9yZUFjdGl2YXRlIGxpZmVjeWNsZSBtZXRob2Rcblx0ICogcmVzb2x2ZXMgdG8gdHJ1ZS5cblx0ICogQHBhcmFtIHshU2NyZWVufSBuZXh0U2NyZWVuXG5cdCAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9XG5cdCAqL1xuXHRtYXliZVByZXZlbnRBY3RpdmF0ZV8obmV4dFNjcmVlbikge1xuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSgpXG5cdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdHJldHVybiBuZXh0U2NyZWVuLmJlZm9yZUFjdGl2YXRlKCk7XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4ocHJldmVudCA9PiB7XG5cdFx0XHRcdGlmIChwcmV2ZW50KSB7XG5cdFx0XHRcdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IoJ0NhbmNlbGxlZCBieSBuZXh0IHNjcmVlbicpKTtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5wZW5kaW5nTmF2aWdhdGU7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENhbmNlbHMgbmF2aWdhdGlvbiBpZiBhY3RpdmVTY3JlZW4ncyBiZWZvcmVEZWFjdGl2YXRlIGxpZmVjeWNsZVxuXHQgKiBtZXRob2QgcmVzb2x2ZXMgdG8gdHJ1ZS5cblx0ICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX1cblx0ICovXG5cdG1heWJlUHJldmVudERlYWN0aXZhdGVfKCkge1xuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSgpXG5cdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdGlmICh0aGlzLmFjdGl2ZVNjcmVlbikge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLmFjdGl2ZVNjcmVlbi5iZWZvcmVEZWFjdGl2YXRlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQudGhlbihwcmV2ZW50ID0+IHtcblx0XHRcdFx0aWYgKHByZXZlbnQpIHtcblx0XHRcdFx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IENhbmNlbGxhYmxlUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxhYmxlUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvcignQ2FuY2VsbGVkIGJ5IGFjdGl2ZSBzY3JlZW4nKSk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMucGVuZGluZ05hdmlnYXRlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSByZXBvc2l0aW9uIHNjcm9sbCB0byBoYXNoZWQgYW5jaG9yLlxuXHQgKi9cblx0bWF5YmVSZXBvc2l0aW9uU2Nyb2xsVG9IYXNoZWRBbmNob3IoKSB7XG5cdFx0Y29uc3QgaGFzaCA9IGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhhc2g7XG5cdFx0aWYgKGhhc2gpIHtcblx0XHRcdGxldCBhbmNob3JFbGVtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChoYXNoLnN1YnN0cmluZygxKSk7XG5cdFx0XHRpZiAoYW5jaG9yRWxlbWVudCkge1xuXHRcdFx0XHRjb25zdCB7b2Zmc2V0TGVmdCwgb2Zmc2V0VG9wfSA9IHV0aWxzLmdldE5vZGVPZmZzZXQoYW5jaG9yRWxlbWVudCk7XG5cdFx0XHRcdGdsb2JhbHMud2luZG93LnNjcm9sbFRvKG9mZnNldExlZnQsIG9mZnNldFRvcCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIElmIHN1cHBvcnRlZCBieSB0aGUgYnJvd3NlciwgcmVzdG9yZXMgbmF0aXZlIHNjcm9sbCByZXN0b3JhdGlvbiB0byB0aGVcblx0ICogdmFsdWUgY2FwdHVyZWQgYnkgYG1heWJlRGlzYWJsZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uYC5cblx0ICovXG5cdG1heWJlUmVzdG9yZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uKCkge1xuXHRcdGlmICh0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uU3VwcG9ydGVkICYmIHRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25fKSB7XG5cdFx0XHRnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uID0gdGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvbl87XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHJlc3RvcmUgcmVkaXJlY3RlZCBwYXRoIGhhc2ggaW4gY2FzZSBib3RoIHRoZSBjdXJyZW50IHBhdGggYW5kXG5cdCAqIHRoZSBnaXZlbiBwYXRoIGFyZSB0aGUgc2FtZS5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggYmVmb3JlIG5hdmlnYXRpb24uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcmVkaXJlY3RQYXRoIFBhdGggYWZ0ZXIgbmF2aWdhdGlvbi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBoYXNoIEhhc2ggdG8gYmUgYWRkZWQgdG8gdGhlIHBhdGguXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9IFJldHVybnMgdGhlIHBhdGggd2l0aCB0aGUgaGFzaCByZXN0b3JlZC5cblx0ICovXG5cdG1heWJlUmVzdG9yZVJlZGlyZWN0UGF0aEhhc2hfKHBhdGgsIHJlZGlyZWN0UGF0aCwgaGFzaCkge1xuXHRcdGlmIChyZWRpcmVjdFBhdGggPT09IHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaChwYXRoKSkge1xuXHRcdFx0cmV0dXJuIHJlZGlyZWN0UGF0aCArIGhhc2g7XG5cdFx0fVxuXHRcdHJldHVybiByZWRpcmVjdFBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgdXBkYXRlIHNjcm9sbCBwb3NpdGlvbiBpbiBoaXN0b3J5IHN0YXRlIHRvIGFuY2hvciBvbiBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIGFuY2hvclxuXHQgKi9cblx0bWF5YmVVcGRhdGVTY3JvbGxQb3NpdGlvblN0YXRlXygpIHtcblx0XHR2YXIgaGFzaCA9IGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhhc2g7XG5cdFx0dmFyIGFuY2hvckVsZW1lbnQgPSBnbG9iYWxzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGhhc2guc3Vic3RyaW5nKDEpKTtcblx0XHRpZiAoYW5jaG9yRWxlbWVudCkge1xuXHRcdFx0Y29uc3Qge29mZnNldExlZnQsIG9mZnNldFRvcH0gPSB1dGlscy5nZXROb2RlT2Zmc2V0KGFuY2hvckVsZW1lbnQpO1xuXHRcdFx0dGhpcy5zYXZlSGlzdG9yeUN1cnJlbnRQYWdlU2Nyb2xsUG9zaXRpb25fKG9mZnNldFRvcCwgb2Zmc2V0TGVmdCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE5hdmlnYXRlcyB0byB0aGUgc3BlY2lmaWVkIHBhdGggaWYgdGhlcmUgaXMgYSByb3V0ZSBoYW5kbGVyIHRoYXQgbWF0Y2hlcy5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggdG8gbmF2aWdhdGUgY29udGFpbmluZyB0aGUgYmFzZSBwYXRoLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmVwbGFjZUhpc3RvcnkgUmVwbGFjZXMgYnJvd3NlciBoaXN0b3J5LlxuXHQgKiBAcGFyYW0ge0V2ZW50PX0gZXZlbnQgT3B0aW9uYWwgZXZlbnQgb2JqZWN0IHRoYXQgdHJpZ2dlcmVkIHRoZSBuYXZpZ2F0aW9uLlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IFJldHVybnMgYSBwZW5kaW5nIHJlcXVlc3QgY2FuY2VsbGFibGUgcHJvbWlzZS5cblx0ICovXG5cdG5hdmlnYXRlKHBhdGgsIG9wdF9yZXBsYWNlSGlzdG9yeSwgb3B0X2V2ZW50KSB7XG5cdFx0aWYgKCF1dGlscy5pc0h0bWw1SGlzdG9yeVN1cHBvcnRlZCgpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0hUTUw1IEhpc3RvcnkgaXMgbm90IHN1cHBvcnRlZC4gU2VubmEgd2lsbCBub3QgaW50ZXJjZXB0IG5hdmlnYXRpb24uJyk7XG5cdFx0fVxuXG5cdFx0aWYgKG9wdF9ldmVudCkge1xuXHRcdFx0Z2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50ID0gb3B0X2V2ZW50LmNhcHR1cmVkRm9ybUVsZW1lbnQ7XG5cdFx0XHRnbG9iYWxzLmNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQgPSBvcHRfZXZlbnQuY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudDtcblx0XHR9XG5cblx0XHQvLyBXaGVuIHJlbG9hZGluZyB0aGUgc2FtZSBwYXRoIGRvIHJlcGxhY2VTdGF0ZSBpbnN0ZWFkIG9mIHB1c2hTdGF0ZSB0b1xuXHRcdC8vIGF2b2lkIHBvbGx1dGluZyBoaXN0b3J5IHdpdGggc3RhdGVzIHdpdGggdGhlIHNhbWUgcGF0aC5cblx0XHRpZiAocGF0aCA9PT0gdGhpcy5hY3RpdmVQYXRoKSB7XG5cdFx0XHRvcHRfcmVwbGFjZUhpc3RvcnkgPSB0cnVlO1xuXHRcdH1cblxuXHRcdHRoaXMuZW1pdCgnYmVmb3JlTmF2aWdhdGUnLCB7XG5cdFx0XHRldmVudDogb3B0X2V2ZW50LFxuXHRcdFx0cGF0aDogcGF0aCxcblx0XHRcdHJlcGxhY2VIaXN0b3J5OiAhIW9wdF9yZXBsYWNlSGlzdG9yeVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIHRoaXMucGVuZGluZ05hdmlnYXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEJlZm9yZXMgbmF2aWdhdGlvbiB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGUgY29udGFpbmluZyA8Y29kZT5wYXRoPC9jb2RlPiBhbmRcblx0ICogICAgIDxjb2RlPnJlcGxhY2VIaXN0b3J5PC9jb2RlPi5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25CZWZvcmVOYXZpZ2F0ZV8oZXZlbnQpIHtcblx0XHRpZiAoZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50KSB7XG5cdFx0XHRldmVudC5mb3JtID0gZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50O1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBCZWZvcmVzIG5hdmlnYXRpb24gdG8gYSBwYXRoLiBSdW5zIGFmdGVyIGV4dGVybmFsIGxpc3RlbmVycy5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IEV2ZW50IGZhY2FkZSBjb250YWluaW5nIDxjb2RlPnBhdGg8L2NvZGU+IGFuZFxuXHQgKiAgICAgPGNvZGU+cmVwbGFjZUhpc3Rvcnk8L2NvZGU+LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvbkJlZm9yZU5hdmlnYXRlRGVmYXVsdF8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy5wZW5kaW5nTmF2aWdhdGUpIHtcblx0XHRcdGlmICh0aGlzLnBlbmRpbmdOYXZpZ2F0ZS5wYXRoID09PSBldmVudC5wYXRoIHx8IHRoaXMubmF2aWdhdGlvblN0cmF0ZWd5ID09PSBOYXZpZ2F0aW9uU3RyYXRlZ3kuU0NIRURVTEVfTEFTVCkge1xuXHRcdFx0XHRjb25zb2xlLmxvZygnV2FpdGluZy4uLicpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5lbWl0KCdiZWZvcmVVbmxvYWQnLCBldmVudCk7XG5cblx0XHR0aGlzLmVtaXQoJ3N0YXJ0TmF2aWdhdGUnLCB7XG5cdFx0XHRmb3JtOiBldmVudC5mb3JtLFxuXHRcdFx0cGF0aDogZXZlbnQucGF0aCxcblx0XHRcdHJlcGxhY2VIaXN0b3J5OiBldmVudC5yZXBsYWNlSGlzdG9yeVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEN1c3RvbSBldmVudCBoYW5kbGVyIHRoYXQgZXhlY3V0ZXMgdGhlIG9yaWdpbmFsIGxpc3RlbmVyIHRoYXQgaGFzIGJlZW5cblx0ICogYWRkZWQgYnkgdGhlIGNsaWVudCBjb2RlIGFuZCB0ZXJtaW5hdGVzIHRoZSBuYXZpZ2F0aW9uIGFjY29yZGluZ2x5LlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgb3JpZ2luYWwgRXZlbnQgZmFjYWRlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvbkJlZm9yZVVubG9hZERlZmF1bHRfKGV2ZW50KSB7XG5cdFx0dmFyIGZ1bmMgPSB3aW5kb3cuX29uYmVmb3JldW5sb2FkO1xuXHRcdGlmIChmdW5jICYmICFmdW5jLl9vdmVybG9hZGVkICYmIGZ1bmMoKSkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogSW50ZXJjZXB0cyBkb2N1bWVudCBjbGlja3MgYW5kIHRlc3QgbGluayBlbGVtZW50cyBpbiBvcmRlciB0byBkZWNpZGVcblx0ICogd2hldGhlciBTdXJmYWNlIGFwcCBjYW4gbmF2aWdhdGUuXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGVcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25Eb2NDbGlja0RlbGVnYXRlXyhldmVudCkge1xuXHRcdGlmIChldmVudC5hbHRLZXkgfHwgZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IGV2ZW50LnNoaWZ0S2V5IHx8IGV2ZW50LmJ1dHRvbikge1xuXHRcdFx0Y29uc29sZS5sb2coJ05hdmlnYXRlIGFib3J0ZWQsIGludmFsaWQgbW91c2UgYnV0dG9uIG9yIG1vZGlmaWVyIGtleSBwcmVzc2VkLicpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLm1heWJlTmF2aWdhdGVfKGV2ZW50LmRlbGVnYXRlVGFyZ2V0LmhyZWYsIGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBJbnRlcmNlcHRzIGRvY3VtZW50IGZvcm0gc3VibWl0cyBhbmQgdGVzdCBhY3Rpb24gcGF0aCBpbiBvcmRlciB0byBkZWNpZGVcblx0ICogd2hldGhlciBTdXJmYWNlIGFwcCBjYW4gbmF2aWdhdGUuXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGVcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25Eb2NTdWJtaXREZWxlZ2F0ZV8oZXZlbnQpIHtcblx0XHR2YXIgZm9ybSA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0O1xuXHRcdGlmIChmb3JtLm1ldGhvZCA9PT0gJ2dldCcpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdHRVQgbWV0aG9kIG5vdCBzdXBwb3J0ZWQnKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZXZlbnQuY2FwdHVyZWRGb3JtRWxlbWVudCA9IGZvcm07XG5cdFx0Y29uc3QgYnV0dG9uU2VsZWN0b3IgPSAnYnV0dG9uOm5vdChbdHlwZV0pLGJ1dHRvblt0eXBlPXN1Ym1pdF0saW5wdXRbdHlwZT1zdWJtaXRdJztcblx0XHRpZiAobWF0Y2goZ2xvYmFscy5kb2N1bWVudC5hY3RpdmVFbGVtZW50LCBidXR0b25TZWxlY3RvcikpIHtcblx0XHRcdGV2ZW50LmNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQgPSBnbG9iYWxzLmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGV2ZW50LmNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQgPSBmb3JtLnF1ZXJ5U2VsZWN0b3IoYnV0dG9uU2VsZWN0b3IpO1xuXHRcdH1cblx0XHR0aGlzLm1heWJlTmF2aWdhdGVfKGZvcm0uYWN0aW9uLCBldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogTGlzdGVucyB0byB0aGUgd2luZG93J3MgbG9hZCBldmVudCBpbiBvcmRlciB0byBhdm9pZCBpc3N1ZXMgd2l0aCBzb21lIGJyb3dzZXJzXG5cdCAqIHRoYXQgdHJpZ2dlciBwb3BzdGF0ZSBjYWxscyBvbiB0aGUgZmlyc3QgbG9hZC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlXG5cdCAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjQyMTc2OS9wb3BzdGF0ZS1vbi1wYWdlcy1sb2FkLWluLWNocm9tZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25Mb2FkXygpIHtcblx0XHR0aGlzLnNraXBMb2FkUG9wc3RhdGUgPSB0cnVlO1xuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0Ly8gVGhlIHRpbWVvdXQgZW5zdXJlcyB0aGF0IHBvcHN0YXRlIGV2ZW50cyB3aWxsIGJlIHVuYmxvY2tlZCByaWdodFxuXHRcdFx0Ly8gYWZ0ZXIgdGhlIGxvYWQgZXZlbnQgb2NjdXJlZCwgYnV0IG5vdCBpbiB0aGUgc2FtZSBldmVudC1sb29wIGN5Y2xlLlxuXHRcdFx0dGhpcy5za2lwTG9hZFBvcHN0YXRlID0gZmFsc2U7XG5cdFx0fSwgMCk7XG5cdFx0Ly8gVHJ5IHRvIHJlcG9zaXRpb24gc2Nyb2xsIHRvIHRoZSBoYXNoZWQgYW5jaG9yIHdoZW4gcGFnZSBsb2Fkcy5cblx0XHR0aGlzLm1heWJlUmVwb3NpdGlvblNjcm9sbFRvSGFzaGVkQW5jaG9yKCk7XG5cdH1cblxuXHQvKipcblx0ICogSGFuZGxlcyBicm93c2VyIGhpc3RvcnkgY2hhbmdlcyBhbmQgZmlyZXMgYXBwJ3MgbmF2aWdhdGlvbiBpZiB0aGUgc3RhdGVcblx0ICogYmVsb3dzIHRvIHVzLiBJZiB3ZSBkZXRlY3QgYSBwb3BzdGF0ZSBhbmQgdGhlIHN0YXRlIGlzIDxjb2RlPm51bGw8L2NvZGU+LFxuXHQgKiBhc3N1bWUgaXQgaXMgbmF2aWdhdGluZyB0byBhbiBleHRlcm5hbCBwYWdlIG9yIHRvIGEgcGFnZSB3ZSBkb24ndCBoYXZlXG5cdCAqIHJvdXRlLCB0aGVuIDxjb2RlPmdsb2JhbHMud2luZG93LmxvY2F0aW9uLnJlbG9hZCgpPC9jb2RlPiBpcyBpbnZva2VkIGluIG9yZGVyIHRvXG5cdCAqIHJlbG9hZCB0aGUgY29udGVudCB0byB0aGUgY3VycmVudCB1cmwuXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGVcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25Qb3BzdGF0ZV8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy5za2lwTG9hZFBvcHN0YXRlKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRG8gbm90IG5hdmlnYXRlIGlmIHRoZSBwb3BzdGF0ZSB3YXMgdHJpZ2dlcmVkIGJ5IGEgaGFzaCBjaGFuZ2UuXG5cdFx0aWYgKHV0aWxzLmlzQ3VycmVudEJyb3dzZXJQYXRoKHRoaXMuYnJvd3NlclBhdGhCZWZvcmVOYXZpZ2F0ZSkpIHtcblx0XHRcdHRoaXMubWF5YmVSZXBvc2l0aW9uU2Nyb2xsVG9IYXNoZWRBbmNob3IoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgc3RhdGUgPSBldmVudC5zdGF0ZTtcblxuXHRcdGlmICghc3RhdGUpIHtcblx0XHRcdGlmIChnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoKSB7XG5cdFx0XHRcdC8vIElmIHNlbm5hIGlzIG9uIGFuIHJlZGlyZWN0IHBhdGggYW5kIGEgaGFzaCBwb3BzdGF0ZSBoYXBwZW5zXG5cdFx0XHRcdC8vIHRvIGEgZGlmZmVyZW50IHVybCwgcmVsb2FkIHRoZSBicm93c2VyLiBUaGlzIGJlaGF2aW9yIGRvZXNuJ3Rcblx0XHRcdFx0Ly8gcmVxdWlyZSBzZW5uYSB0byByb3V0ZSBoYXNoZWQgbGlua3MgYW5kIGlzIGNsb3NlciB0byBuYXRpdmVcblx0XHRcdFx0Ly8gYnJvd3NlciBiZWhhdmlvci5cblx0XHRcdFx0aWYgKHRoaXMucmVkaXJlY3RQYXRoICYmICF1dGlscy5pc0N1cnJlbnRCcm93c2VyUGF0aCh0aGlzLnJlZGlyZWN0UGF0aCkpIHtcblx0XHRcdFx0XHR0aGlzLnJlbG9hZFBhZ2UoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBBbHdheXMgdHJ5IHRvIHJlcG9zaXRpb24gc2Nyb2xsIHRvIHRoZSBoYXNoZWQgYW5jaG9yIHdoZW5cblx0XHRcdFx0Ly8gaGFzaCBwb3BzdGF0ZSBoYXBwZW5zLlxuXHRcdFx0XHR0aGlzLm1heWJlUmVwb3NpdGlvblNjcm9sbFRvSGFzaGVkQW5jaG9yKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnJlbG9hZFBhZ2UoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoc3RhdGUuc2VubmEpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdIaXN0b3J5IG5hdmlnYXRpb24gdG8gWycgKyBzdGF0ZS5wYXRoICsgJ10nKTtcblx0XHRcdHRoaXMucG9wc3RhdGVTY3JvbGxUb3AgPSBzdGF0ZS5zY3JvbGxUb3A7XG5cdFx0XHR0aGlzLnBvcHN0YXRlU2Nyb2xsTGVmdCA9IHN0YXRlLnNjcm9sbExlZnQ7XG5cdFx0XHRpZiAoIXRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25TdXBwb3J0ZWQpIHtcblx0XHRcdFx0dGhpcy5sb2NrSGlzdG9yeVNjcm9sbFBvc2l0aW9uXygpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5vbmNlKCdlbmROYXZpZ2F0ZScsICgpID0+IHtcblx0XHRcdFx0aWYgKHN0YXRlLnJlZmVycmVyKSB7XG5cdFx0XHRcdFx0dXRpbHMuc2V0UmVmZXJyZXIoc3RhdGUucmVmZXJyZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHRcdGNvbnN0IHVyaSA9IG5ldyBVcmkoc3RhdGUucGF0aCk7XG5cdFx0XHR1cmkuc2V0SG9zdG5hbWUoZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaG9zdG5hbWUpO1xuXHRcdFx0dXJpLnNldFBvcnQoZ2xvYmFscy53aW5kb3cubG9jYXRpb24ucG9ydCk7XG5cdFx0XHRjb25zdCBpc05hdmlnYXRpb25TY2hlZHVsZWQgPSB0aGlzLm1heWJlU2NoZWR1bGVOYXZpZ2F0aW9uXyh1cmkudG9TdHJpbmcoKSwge30pO1xuXHRcdFx0aWYgKGlzTmF2aWdhdGlvblNjaGVkdWxlZCkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHR0aGlzLm5hdmlnYXRlKHN0YXRlLnBhdGgsIHRydWUpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBMaXN0ZW5zIGRvY3VtZW50IHNjcm9sbCBjaGFuZ2VzIGluIG9yZGVyIHRvIGNhcHR1cmUgdGhlIHBvc3NpYmxlIGxvY2tcblx0ICogc2Nyb2xsIHBvc2l0aW9uIGZvciBoaXN0b3J5IHNjcm9sbGluZy5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25TY3JvbGxfKCkge1xuXHRcdGlmICh0aGlzLmNhcHR1cmVTY3JvbGxQb3NpdGlvbkZyb21TY3JvbGxFdmVudCkge1xuXHRcdFx0dGhpcy5zYXZlSGlzdG9yeUN1cnJlbnRQYWdlU2Nyb2xsUG9zaXRpb25fKGdsb2JhbHMud2luZG93LnBhZ2VZT2Zmc2V0LCBnbG9iYWxzLndpbmRvdy5wYWdlWE9mZnNldCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFN0YXJ0cyBuYXZpZ2F0aW9uIHRvIGEgcGF0aC5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IEV2ZW50IGZhY2FkZSBjb250YWluaW5nIDxjb2RlPnBhdGg8L2NvZGU+IGFuZFxuXHQgKiAgICAgPGNvZGU+cmVwbGFjZUhpc3Rvcnk8L2NvZGU+LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRvblN0YXJ0TmF2aWdhdGVfKGV2ZW50KSB7XG5cdFx0dGhpcy5tYXliZURpc2FibGVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbigpO1xuXHRcdHRoaXMuY2FwdHVyZVNjcm9sbFBvc2l0aW9uRnJvbVNjcm9sbEV2ZW50ID0gZmFsc2U7XG5cdFx0YWRkQ2xhc3NlcyhnbG9iYWxzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgdGhpcy5sb2FkaW5nQ3NzQ2xhc3MpO1xuXG5cdFx0dmFyIGVuZE5hdmlnYXRlUGF5bG9hZCA9IHtcblx0XHRcdGZvcm06IGV2ZW50LmZvcm0sXG5cdFx0XHRwYXRoOiBldmVudC5wYXRoXG5cdFx0fTtcblxuXHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gdGhpcy5kb05hdmlnYXRlXyhldmVudC5wYXRoLCBldmVudC5yZXBsYWNlSGlzdG9yeSlcblx0XHRcdC5jYXRjaCgocmVhc29uKSA9PiB7XG5cdFx0XHRcdGVuZE5hdmlnYXRlUGF5bG9hZC5lcnJvciA9IHJlYXNvbjtcblx0XHRcdFx0dGhyb3cgcmVhc29uO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuQWx3YXlzKCgpID0+IHtcblx0XHRcdFx0aWYgKCF0aGlzLnBlbmRpbmdOYXZpZ2F0ZSAmJiAhdGhpcy5zY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUubGVuZ3RoKSB7XG5cdFx0XHRcdFx0cmVtb3ZlQ2xhc3NlcyhnbG9iYWxzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgdGhpcy5sb2FkaW5nQ3NzQ2xhc3MpO1xuXHRcdFx0XHRcdHRoaXMubWF5YmVSZXN0b3JlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb24oKTtcblx0XHRcdFx0XHR0aGlzLmNhcHR1cmVTY3JvbGxQb3NpdGlvbkZyb21TY3JvbGxFdmVudCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5lbWl0KCdlbmROYXZpZ2F0ZScsIGVuZE5hdmlnYXRlUGF5bG9hZCk7XG5cdFx0XHR9KTtcblxuXHRcdHRoaXMucGVuZGluZ05hdmlnYXRlLnBhdGggPSBldmVudC5wYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFByZWZldGNoZXMgdGhlIHNwZWNpZmllZCBwYXRoIGlmIHRoZXJlIGlzIGEgcm91dGUgaGFuZGxlciB0aGF0IG1hdGNoZXMuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIHRvIG5hdmlnYXRlIGNvbnRhaW5pbmcgdGhlIGJhc2UgcGF0aC5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfSBSZXR1cm5zIGEgcGVuZGluZyByZXF1ZXN0IGNhbmNlbGxhYmxlIHByb21pc2UuXG5cdCAqL1xuXHRwcmVmZXRjaChwYXRoKSB7XG5cdFx0dmFyIHJvdXRlID0gdGhpcy5maW5kUm91dGUocGF0aCk7XG5cdFx0aWYgKCFyb3V0ZSkge1xuXHRcdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZWplY3QobmV3IENhbmNlbGxhYmxlUHJvbWlzZS5DYW5jZWxsYXRpb25FcnJvcignTm8gcm91dGUgZm9yICcgKyBwYXRoKSk7XG5cdFx0fVxuXG5cdFx0Y29uc29sZS5sb2coJ1ByZWZldGNoaW5nIFsnICsgcGF0aCArICddJyk7XG5cblx0XHR2YXIgbmV4dFNjcmVlbiA9IHRoaXMuY3JlYXRlU2NyZWVuSW5zdGFuY2UocGF0aCwgcm91dGUpO1xuXG5cdFx0cmV0dXJuIG5leHRTY3JlZW4ubG9hZChwYXRoKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5zY3JlZW5zW3BhdGhdID0gbmV4dFNjcmVlbilcblx0XHRcdC5jYXRjaCgocmVhc29uKSA9PiB7XG5cdFx0XHRcdHRoaXMuaGFuZGxlTmF2aWdhdGVFcnJvcl8ocGF0aCwgbmV4dFNjcmVlbiwgcmVhc29uKTtcblx0XHRcdFx0dGhyb3cgcmVhc29uO1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUHJlcGFyZXMgc2NyZWVuIGZsaXAuIFVwZGF0ZXMgaGlzdG9yeSBzdGF0ZSBhbmQgc3VyZmFjZXMgY29udGVudC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHBhcmFtIHshU2NyZWVufSBuZXh0U2NyZWVuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZXBsYWNlSGlzdG9yeSBSZXBsYWNlcyBicm93c2VyIGhpc3RvcnkuXG5cdCAqL1xuXHRwcmVwYXJlTmF2aWdhdGVIaXN0b3J5XyhwYXRoLCBuZXh0U2NyZWVuLCBvcHRfcmVwbGFjZUhpc3RvcnkpIHtcblx0XHRsZXQgdGl0bGUgPSBuZXh0U2NyZWVuLmdldFRpdGxlKCk7XG5cdFx0aWYgKCFpc1N0cmluZyh0aXRsZSkpIHtcblx0XHRcdHRpdGxlID0gdGhpcy5nZXREZWZhdWx0VGl0bGUoKTtcblx0XHR9XG5cdFx0bGV0IHJlZGlyZWN0UGF0aCA9IG5leHRTY3JlZW4uYmVmb3JlVXBkYXRlSGlzdG9yeVBhdGgocGF0aCk7XG5cdFx0Y29uc3QgaGlzdG9yeVN0YXRlID0ge1xuXHRcdFx0Zm9ybTogaXNEZWZBbmROb3ROdWxsKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCksXG5cdFx0XHRwYXRoLFxuXHRcdFx0cmVkaXJlY3RQYXRoLFxuXHRcdFx0c2Nyb2xsTGVmdDogMCxcblx0XHRcdHNjcm9sbFRvcDogMCxcblx0XHRcdHNlbm5hOiB0cnVlXG5cdFx0fTtcblx0XHRpZiAob3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0XHRoaXN0b3J5U3RhdGUuc2Nyb2xsVG9wID0gdGhpcy5wb3BzdGF0ZVNjcm9sbFRvcDtcblx0XHRcdGhpc3RvcnlTdGF0ZS5zY3JvbGxMZWZ0ID0gdGhpcy5wb3BzdGF0ZVNjcm9sbExlZnQ7XG5cdFx0fVxuXHRcdGNvbnN0IGhhc2ggPSBuZXcgVXJpKHBhdGgpLmdldEhhc2goKTtcblx0XHRyZWRpcmVjdFBhdGggPSB0aGlzLm1heWJlUmVzdG9yZVJlZGlyZWN0UGF0aEhhc2hfKHBhdGgsIHJlZGlyZWN0UGF0aCwgaGFzaCk7XG5cdFx0dGhpcy51cGRhdGVIaXN0b3J5Xyh0aXRsZSwgcmVkaXJlY3RQYXRoLCBuZXh0U2NyZWVuLmJlZm9yZVVwZGF0ZUhpc3RvcnlTdGF0ZShoaXN0b3J5U3RhdGUpLCBvcHRfcmVwbGFjZUhpc3RvcnkpO1xuXHRcdHRoaXMucmVkaXJlY3RQYXRoID0gcmVkaXJlY3RQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFByZXBhcmVzIHNjcmVlbiBmbGlwLiBVcGRhdGVzIGhpc3Rvcnkgc3RhdGUgYW5kIHN1cmZhY2VzIGNvbnRlbnQuXG5cdCAqIEBwYXJhbSB7IVNjcmVlbn0gbmV4dFNjcmVlblxuXHQgKiBAcGFyYW0geyFPYmplY3R9IHN1cmZhY2VzIE1hcCBvZiBzdXJmYWNlcyB0byBmbGlwIGtleWVkIGJ5IHN1cmZhY2UgaWQuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gcGFyYW1zIFBhcmFtcyBleHRyYWN0ZWQgZnJvbSB0aGUgY3VycmVudCBwYXRoLlxuXHQgKi9cblx0cHJlcGFyZU5hdmlnYXRlU3VyZmFjZXNfKG5leHRTY3JlZW4sIHN1cmZhY2VzLCBwYXJhbXMpIHtcblx0XHRPYmplY3Qua2V5cyhzdXJmYWNlcykuZm9yRWFjaCgoaWQpID0+IHtcblx0XHRcdHZhciBzdXJmYWNlQ29udGVudCA9IG5leHRTY3JlZW4uZ2V0U3VyZmFjZUNvbnRlbnQoaWQsIHBhcmFtcyk7XG5cdFx0XHRzdXJmYWNlc1tpZF0uYWRkQ29udGVudChuZXh0U2NyZWVuLmdldElkKCksIHN1cmZhY2VDb250ZW50KTtcblx0XHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyBuZXh0U2NyZWVuLmdldElkKCkgKyAnXSBhZGQgY29udGVudCB0byBzdXJmYWNlICcgK1xuXHRcdFx0XHQnWycgKyBzdXJmYWNlc1tpZF0gKyAnXSBbJyArIChpc0RlZkFuZE5vdE51bGwoc3VyZmFjZUNvbnRlbnQpID8gJy4uLicgOiAnZW1wdHknKSArICddJyk7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVsb2FkcyB0aGUgcGFnZSBieSBwZXJmb3JtaW5nIGB3aW5kb3cubG9jYXRpb24ucmVsb2FkKClgLlxuXHQgKi9cblx0cmVsb2FkUGFnZSgpIHtcblx0XHRnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHJvdXRlIGluc3RhbmNlIGZyb20gYXBwIHJvdXRlcy5cblx0ICogQHBhcmFtIHtSb3V0ZX0gcm91dGVcblx0ICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBhbiBlbGVtZW50IHdhcyByZW1vdmVkLlxuXHQgKi9cblx0cmVtb3ZlUm91dGUocm91dGUpIHtcblx0XHRyZXR1cm4gYXJyYXkucmVtb3ZlKHRoaXMucm91dGVzLCByb3V0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBhIHNjcmVlbi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICovXG5cdHJlbW92ZVNjcmVlbihwYXRoKSB7XG5cdFx0dmFyIHNjcmVlbiA9IHRoaXMuc2NyZWVuc1twYXRoXTtcblx0XHRpZiAoc2NyZWVuKSB7XG5cdFx0XHRPYmplY3Qua2V5cyh0aGlzLnN1cmZhY2VzKS5mb3JFYWNoKChzdXJmYWNlSWQpID0+IHRoaXMuc3VyZmFjZXNbc3VyZmFjZUlkXS5yZW1vdmUoc2NyZWVuLmdldElkKCkpKTtcblx0XHRcdHNjcmVlbi5kaXNwb3NlKCk7XG5cdFx0XHRkZWxldGUgdGhpcy5zY3JlZW5zW3BhdGhdO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTYXZlcyBnaXZlbiBzY3JvbGwgcG9zaXRpb24gaW50byBoaXN0b3J5IHN0YXRlLlxuXHQgKiBAcGFyYW0geyFudW1iZXJ9IHNjcm9sbFRvcCBOdW1iZXIgY29udGFpbmluZyB0aGUgdG9wIHNjcm9sbCBwb3NpdGlvbiB0byBiZSBzYXZlZC5cblx0ICogQHBhcmFtIHshbnVtYmVyfSBzY3JvbGxMZWZ0IE51bWJlciBjb250YWluaW5nIHRoZSBsZWZ0IHNjcm9sbCBwb3NpdGlvbiB0byBiZSBzYXZlZC5cblx0ICovXG5cdHNhdmVIaXN0b3J5Q3VycmVudFBhZ2VTY3JvbGxQb3NpdGlvbl8oc2Nyb2xsVG9wLCBzY3JvbGxMZWZ0KSB7XG5cdFx0dmFyIHN0YXRlID0gZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5zdGF0ZTtcblx0XHRpZiAoc3RhdGUgJiYgc3RhdGUuc2VubmEpIHtcblx0XHRcdFtzdGF0ZS5zY3JvbGxUb3AsIHN0YXRlLnNjcm9sbExlZnRdID0gW3Njcm9sbFRvcCwgc2Nyb2xsTGVmdF07XG5cdFx0XHRnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShzdGF0ZSwgbnVsbCwgbnVsbCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgYWxsb3cgcHJldmVudCBuYXZpZ2F0ZS5cblx0ICogQHBhcmFtIHtib29sZWFufSBhbGxvd1ByZXZlbnROYXZpZ2F0ZVxuXHQgKi9cblx0c2V0QWxsb3dQcmV2ZW50TmF2aWdhdGUoYWxsb3dQcmV2ZW50TmF2aWdhdGUpIHtcblx0XHR0aGlzLmFsbG93UHJldmVudE5hdmlnYXRlID0gYWxsb3dQcmV2ZW50TmF2aWdhdGU7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBsaW5rIGJhc2UgcGF0aC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoXG5cdCAqL1xuXHRzZXRCYXNlUGF0aChiYXNlUGF0aCkge1xuXHRcdHRoaXMuYmFzZVBhdGggPSB1dGlscy5yZW1vdmVQYXRoVHJhaWxpbmdTbGFzaChiYXNlUGF0aCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgZGVmYXVsdCBwYWdlIHRpdGxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZGVmYXVsdFRpdGxlXG5cdCAqL1xuXHRzZXREZWZhdWx0VGl0bGUoZGVmYXVsdFRpdGxlKSB7XG5cdFx0dGhpcy5kZWZhdWx0VGl0bGUgPSBkZWZhdWx0VGl0bGU7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgZm9ybSBzZWxlY3Rvci5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBmb3JtU2VsZWN0b3Jcblx0ICovXG5cdHNldEZvcm1TZWxlY3Rvcihmb3JtU2VsZWN0b3IpIHtcblx0XHR0aGlzLmZvcm1TZWxlY3RvciA9IGZvcm1TZWxlY3Rvcjtcblx0XHRpZiAodGhpcy5mb3JtRXZlbnRIYW5kbGVyXykge1xuXHRcdFx0dGhpcy5mb3JtRXZlbnRIYW5kbGVyXy5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdH1cblx0XHR0aGlzLmZvcm1FdmVudEhhbmRsZXJfID0gZGVsZWdhdGUoZG9jdW1lbnQsICdzdWJtaXQnLCB0aGlzLmZvcm1TZWxlY3RvciwgdGhpcy5vbkRvY1N1Ym1pdERlbGVnYXRlXy5iaW5kKHRoaXMpLCB0aGlzLmFsbG93UHJldmVudE5hdmlnYXRlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIGlmIHJvdXRlIG1hdGNoaW5nIHNob3VsZCBpZ25vcmUgcXVlcnkgc3RyaW5nIGZyb20gdGhlIHJvdXRlIHBhdGguXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoXG5cdCAqL1xuXHRzZXRJZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGgoaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoKSB7XG5cdFx0dGhpcy5pZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGggPSBpZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgbGluayBzZWxlY3Rvci5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBsaW5rU2VsZWN0b3Jcblx0ICovXG5cdHNldExpbmtTZWxlY3RvcihsaW5rU2VsZWN0b3IpIHtcblx0XHR0aGlzLmxpbmtTZWxlY3RvciA9IGxpbmtTZWxlY3Rvcjtcblx0XHRpZiAodGhpcy5saW5rRXZlbnRIYW5kbGVyXykge1xuXHRcdFx0dGhpcy5saW5rRXZlbnRIYW5kbGVyXy5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdH1cblx0XHR0aGlzLmxpbmtFdmVudEhhbmRsZXJfID0gZGVsZWdhdGUoZG9jdW1lbnQsICdjbGljaycsIHRoaXMubGlua1NlbGVjdG9yLCB0aGlzLm9uRG9jQ2xpY2tEZWxlZ2F0ZV8uYmluZCh0aGlzKSwgdGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgbG9hZGluZyBjc3MgY2xhc3MuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gbG9hZGluZ0Nzc0NsYXNzXG5cdCAqL1xuXHRzZXRMb2FkaW5nQ3NzQ2xhc3MobG9hZGluZ0Nzc0NsYXNzKSB7XG5cdFx0dGhpcy5sb2FkaW5nQ3NzQ2xhc3MgPSBsb2FkaW5nQ3NzQ2xhc3M7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdXBkYXRlIHNjcm9sbCBwb3NpdGlvbiB2YWx1ZS5cblx0ICogQHBhcmFtIHtib29sZWFufSB1cGRhdGVTY3JvbGxQb3NpdGlvblxuXHQgKi9cblx0c2V0VXBkYXRlU2Nyb2xsUG9zaXRpb24odXBkYXRlU2Nyb2xsUG9zaXRpb24pIHtcblx0XHR0aGlzLnVwZGF0ZVNjcm9sbFBvc2l0aW9uID0gdXBkYXRlU2Nyb2xsUG9zaXRpb247XG5cdH1cblxuXHQvKipcblx0ICogQ2FuY2VscyBwZW5kaW5nIG5hdmlnYXRlIHdpdGggPGNvZGU+Q2FuY2VsIHBlbmRpbmcgbmF2aWdhdGlvbjwvY29kZT4gZXJyb3IuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHN0b3BQZW5kaW5nTmF2aWdhdGVfKCkge1xuXHRcdGlmICh0aGlzLnBlbmRpbmdOYXZpZ2F0ZSkge1xuXHRcdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUuY2FuY2VsKCdDYW5jZWwgcGVuZGluZyBuYXZpZ2F0aW9uJyk7XG5cdFx0fVxuXHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTeW5jIGRvY3VtZW50IHNjcm9sbCBwb3NpdGlvbiB0d2ljZSwgdGhlIGZpcnN0IG9uZSBzeW5jaHJvbm91cyBhbmQgdGhlblxuXHQgKiBvbmUgaW5zaWRlIDxjb2RlPmFzeW5jLm5leHRUaWNrPC9jb2RlPi4gUmVsZXZhbnQgdG8gYnJvd3NlcnMgdGhhdCBmaXJlc1xuXHQgKiBzY3JvbGwgcmVzdG9yYXRpb24gYXN5bmNocm9ub3VzbHkgYWZ0ZXIgcG9wc3RhdGUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQHJldHVybiB7P0NhbmNlbGxhYmxlUHJvbWlzZT19XG5cdCAqL1xuXHRzeW5jU2Nyb2xsUG9zaXRpb25TeW5jVGhlbkFzeW5jXygpIHtcblx0XHR2YXIgc3RhdGUgPSBnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnN0YXRlO1xuXHRcdGlmICghc3RhdGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgc2Nyb2xsVG9wID0gc3RhdGUuc2Nyb2xsVG9wO1xuXHRcdHZhciBzY3JvbGxMZWZ0ID0gc3RhdGUuc2Nyb2xsTGVmdDtcblxuXHRcdHZhciBzeW5jID0gKCkgPT4ge1xuXHRcdFx0aWYgKHRoaXMudXBkYXRlU2Nyb2xsUG9zaXRpb24pIHtcblx0XHRcdFx0Z2xvYmFscy53aW5kb3cuc2Nyb2xsVG8oc2Nyb2xsTGVmdCwgc2Nyb2xsVG9wKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0cmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUpID0+IHN5bmMoKSAmIGFzeW5jLm5leHRUaWNrKCgpID0+IHN5bmMoKSAmIHJlc29sdmUoKSkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZXMgb3IgcmVwbGFjZSBicm93c2VyIGhpc3RvcnkuXG5cdCAqIEBwYXJhbSB7P3N0cmluZ30gdGl0bGUgRG9jdW1lbnQgdGl0bGUuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEBwYXJhbSB7IW9iamVjdH0gc3RhdGVcblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JlcGxhY2VIaXN0b3J5IFJlcGxhY2VzIGJyb3dzZXIgaGlzdG9yeS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0dXBkYXRlSGlzdG9yeV8odGl0bGUsIHBhdGgsIHN0YXRlLCBvcHRfcmVwbGFjZUhpc3RvcnkpIHtcblx0XHRjb25zdCByZWZlcnJlciA9IGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhyZWY7XG5cblx0XHRpZiAoc3RhdGUpIHtcblx0XHRcdHN0YXRlLnJlZmVycmVyID0gcmVmZXJyZXI7XG5cdFx0fVxuXG5cdFx0aWYgKG9wdF9yZXBsYWNlSGlzdG9yeSkge1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoc3RhdGUsIHRpdGxlLCBwYXRoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUoc3RhdGUsIHRpdGxlLCBwYXRoKTtcblx0XHR9XG5cblx0XHR1dGlscy5zZXRSZWZlcnJlcihyZWZlcnJlcik7XG5cblx0XHRsZXQgdGl0bGVOb2RlID0gZ2xvYmFscy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd0aXRsZScpO1xuXHRcdGlmICh0aXRsZU5vZGUpIHtcblx0XHRcdHRpdGxlTm9kZS5pbm5lckhUTUwgPSB0aXRsZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Z2xvYmFscy5kb2N1bWVudC50aXRsZSA9IHRpdGxlO1xuXHRcdH1cblx0fVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IEFwcDtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgaXNEZWYsIGlzRGVmQW5kTm90TnVsbCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCBVcmkgZnJvbSAnbWV0YWwtdXJpJztcbmltcG9ydCB7IENhbmNlbGxhYmxlUHJvbWlzZSBhcyBQcm9taXNlIH0gZnJvbSAnbWV0YWwtcHJvbWlzZSc7XG5cbmNsYXNzIEFqYXgge1xuXG5cdC8qKlxuXHQgKiBYbWxIdHRwUmVxdWVzdCdzIGdldEFsbFJlc3BvbnNlSGVhZGVycygpIG1ldGhvZCByZXR1cm5zIGEgc3RyaW5nIG9mXG5cdCAqIHJlc3BvbnNlIGhlYWRlcnMgYWNjb3JkaW5nIHRvIHRoZSBmb3JtYXQgZGVzY3JpYmVkIG9uIHRoZSBzcGVjOlxuXHQgKiB7QGxpbmsgaHR0cDovL3d3dy53My5vcmcvVFIvWE1MSHR0cFJlcXVlc3QvI3RoZS1nZXRhbGxyZXNwb25zZWhlYWRlcnMtbWV0aG9kfS5cblx0ICogVGhpcyBtZXRob2QgcGFyc2VzIHRoYXQgc3RyaW5nIGludG8gYSB1c2VyLWZyaWVuZGx5IG5hbWUvdmFsdWUgcGFpclxuXHQgKiBvYmplY3QuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBhbGxIZWFkZXJzIEFsbCBoZWFkZXJzIGFzIHN0cmluZy5cblx0ICogQHJldHVybiB7IUFycmF5LjxPYmplY3Q8c3RyaW5nLCBzdHJpbmc+Pn1cblx0ICovXG5cdHN0YXRpYyBwYXJzZVJlc3BvbnNlSGVhZGVycyhhbGxIZWFkZXJzKSB7XG5cdFx0dmFyIGhlYWRlcnMgPSBbXTtcblx0XHRpZiAoIWFsbEhlYWRlcnMpIHtcblx0XHRcdHJldHVybiBoZWFkZXJzO1xuXHRcdH1cblx0XHR2YXIgcGFpcnMgPSBhbGxIZWFkZXJzLnNwbGl0KCdcXHUwMDBkXFx1MDAwYScpO1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgcGFpcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBpbmRleCA9IHBhaXJzW2ldLmluZGV4T2YoJ1xcdTAwM2FcXHUwMDIwJyk7XG5cdFx0XHRpZiAoaW5kZXggPiAwKSB7XG5cdFx0XHRcdHZhciBuYW1lID0gcGFpcnNbaV0uc3Vic3RyaW5nKDAsIGluZGV4KTtcblx0XHRcdFx0dmFyIHZhbHVlID0gcGFpcnNbaV0uc3Vic3RyaW5nKGluZGV4ICsgMik7XG5cdFx0XHRcdGhlYWRlcnMucHVzaCh7XG5cdFx0XHRcdFx0bmFtZTogbmFtZSxcblx0XHRcdFx0XHR2YWx1ZTogdmFsdWVcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBoZWFkZXJzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlcXVlc3RzIHRoZSB1cmwgdXNpbmcgWE1MSHR0cFJlcXVlc3QuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gdXJsXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gbWV0aG9kXG5cdCAqIEBwYXJhbSB7P3N0cmluZ30gYm9keVxuXHQgKiBAcGFyYW0ge011bHRpTWFwPX0gb3B0X2hlYWRlcnNcblx0ICogQHBhcmFtIHtNdWx0aU1hcD19IG9wdF9wYXJhbXNcblx0ICogQHBhcmFtIHtudW1iZXI9fSBvcHRfdGltZW91dFxuXHQgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc3luY1xuXHQgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfd2l0aENyZWRlbnRpYWxzXG5cdCAqIEByZXR1cm4ge1Byb21pc2V9IERlZmVycmVkIGFqYXggcmVxdWVzdC5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0c3RhdGljIHJlcXVlc3QodXJsLCBtZXRob2QsIGJvZHksIG9wdF9oZWFkZXJzLCBvcHRfcGFyYW1zLCBvcHRfdGltZW91dCwgb3B0X3N5bmMsIG9wdF93aXRoQ3JlZGVudGlhbHMpIHtcblx0XHR1cmwgPSB1cmwgfHwgJyc7XG5cdFx0bWV0aG9kID0gbWV0aG9kIHx8ICdHRVQnO1xuXG5cdFx0dmFyIHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblx0XHR2YXIgcHJldmlvdXNSZWFkeVN0YXRlID0gMDtcblxuXHRcdHZhciBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdFx0XHRyZXF1ZXN0Lm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAocmVxdWVzdC5hYm9ydGVkKSB7XG5cdFx0XHRcdFx0cmVxdWVzdC5vbmVycm9yKCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJlc29sdmUocmVxdWVzdCk7XG5cdFx0XHR9O1xuXHRcdFx0cmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKHByZXZpb3VzUmVhZHlTdGF0ZSAmJiBwcmV2aW91c1JlYWR5U3RhdGUgPCAzICYmIDQgPT09IHJlcXVlc3QucmVhZHlTdGF0ZSkge1xuXHRcdFx0XHRcdHJlcXVlc3QudGVybWluYXRlZFByZW1hdHVyZWx5ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRwcmV2aW91c1JlYWR5U3RhdGUgPSByZXF1ZXN0LnJlYWR5U3RhdGU7XG5cdFx0XHR9O1xuXHRcdFx0cmVxdWVzdC5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBtZXNzYWdlID0gJ1JlcXVlc3QgZXJyb3InO1xuXHRcdFx0XHRpZiAocmVxdWVzdC50ZXJtaW5hdGVkUHJlbWF0dXJlbHkpIHtcblx0XHRcdFx0XHRtZXNzYWdlID0gJ1JlcXVlc3QgdGVybWluYXRlZCBwcmVtYXR1cmVseSc7XG5cdFx0XHRcdH0gXG5cdFx0XHRcdHZhciBlcnJvciA9IG5ldyBFcnJvcihtZXNzYWdlKTtcblx0XHRcdFx0ZXJyb3IucmVxdWVzdCA9IHJlcXVlc3Q7XG5cdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHR9O1xuXHRcdH0pLnRoZW5DYXRjaChmdW5jdGlvbihyZWFzb24pIHtcblx0XHRcdHJlcXVlc3QuYWJvcnQoKTtcblx0XHRcdHRocm93IHJlYXNvbjtcblx0XHR9KS50aGVuQWx3YXlzKGZ1bmN0aW9uKCkge1xuXHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXHRcdH0pO1xuXG5cdFx0dXJsID0gbmV3IFVyaSh1cmwpO1xuXG5cdFx0aWYgKG9wdF9wYXJhbXMpIHtcblx0XHRcdHVybC5hZGRQYXJhbWV0ZXJzRnJvbU11bHRpTWFwKG9wdF9wYXJhbXMpLnRvU3RyaW5nKCk7XG5cdFx0fVxuXG5cdFx0dXJsID0gdXJsLnRvU3RyaW5nKCk7XG5cblx0XHRyZXF1ZXN0Lm9wZW4obWV0aG9kLCB1cmwsICFvcHRfc3luYyk7XG5cblx0XHRpZiAob3B0X3dpdGhDcmVkZW50aWFscykge1xuXHRcdFx0cmVxdWVzdC53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmIChvcHRfaGVhZGVycykge1xuXHRcdFx0b3B0X2hlYWRlcnMubmFtZXMoKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcblx0XHRcdFx0cmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIG9wdF9oZWFkZXJzLmdldEFsbChuYW1lKS5qb2luKCcsICcpKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHJlcXVlc3Quc2VuZChpc0RlZihib2R5KSA/IGJvZHkgOiBudWxsKTtcblxuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwob3B0X3RpbWVvdXQpKSB7XG5cdFx0XHR2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHByb21pc2UuY2FuY2VsKCdSZXF1ZXN0IHRpbWVvdXQnKTtcblx0XHRcdH0sIG9wdF90aW1lb3V0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gcHJvbWlzZTtcblx0fVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IEFqYXg7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogSG9sZHMgdmFsdWUgZXJyb3IgbWVzc2FnZXMuXG4gKiBAY29uc3RcbiAqL1xuY2xhc3MgZXJyb3JzIHtcbn1cblxuLyoqXG4gKiBJbnZhbGlkIHN0YXR1cyBlcnJvciBtZXNzYWdlLlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuZXJyb3JzLklOVkFMSURfU1RBVFVTID0gJ0ludmFsaWQgc3RhdHVzIGNvZGUnO1xuXG4vKipcbiAqIFJlcXVlc3QgZXJyb3IgbWVzc2FnZS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cbmVycm9ycy5SRVFVRVNUX0VSUk9SID0gJ1JlcXVlc3QgZXJyb3InO1xuXG4vKipcbiAqIFJlcXVlc3QgdGltZW91dCBlcnJvciBtZXNzYWdlLlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuZXJyb3JzLlJFUVVFU1RfVElNRU9VVCA9ICdSZXF1ZXN0IHRpbWVvdXQnO1xuXG4vKipcbiAqIFJlcXVlc3QgaXMgYmxvY2tlZCBieSBDT1JTIGlzc3VlIG1lc3NhZ2UuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQHN0YXRpY1xuICovXG5lcnJvcnMuUkVRVUVTVF9QUkVNQVRVUkVfVEVSTUlOQVRJT04gPSAnUmVxdWVzdCB0ZXJtaW5hdGVkIHByZW1hdHVyZWx5JztcblxuZXhwb3J0IGRlZmF1bHQgZXJyb3JzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2lzU2VydmVyU2lkZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIE1ldGFsLmpzIGJyb3dzZXIgdXNlciBhZ2VudCBkZXRlY3Rpb24uIEl0J3MgZXh0cmVtZWx5IHJlY29tbWVuZGVkIHRoZSB1c2FnZVxuICogb2YgZmVhdHVyZSBjaGVja2luZyBvdmVyIGJyb3dzZXIgdXNlciBhZ2VudCBzbmlmZmluZy4gVW5mb3J0dW5hdGVseSwgaW4gc29tZVxuICogc2l0dWF0aW9ucyBmZWF0dXJlIGNoZWNraW5nIGNhbiBiZSBzbG93IG9yIGV2ZW4gaW1wb3NzaWJsZSwgdGhlcmVmb3JlIHVzZVxuICogdGhpcyB1dGlsaXR5IHdpdGggY2F1dGlvbi5cbiAqIEBzZWUgPGEgaHJlZj1cImh0dHA6Ly93d3cudXNlcmFnZW50c3RyaW5nLmNvbS9cIj5Vc2VyIGFnZW50IHN0cmluZ3M8L2E+LlxuICovXG5jbGFzcyBVQSB7XG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBuYXRpdmUgdXNlckFnZW50IHN0cmluZyBmcm9tIG5hdmlnYXRvciBpZiBpdCBleGlzdHMuIElmXG5cdCAqIG5hdmlnYXRvciBvciBuYXZpZ2F0b3IudXNlckFnZW50IHN0cmluZyBpcyBtaXNzaW5nLCByZXR1cm5zIGFuIGVtcHR5XG5cdCAqIHN0cmluZy5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0TmF0aXZlVXNlckFnZW50KCkge1xuXHRcdGxldCBuYXZpZ2F0b3IgPSBVQS5nbG9iYWxzLndpbmRvdyAmJiBVQS5nbG9iYWxzLndpbmRvdy5uYXZpZ2F0b3I7XG5cdFx0aWYgKG5hdmlnYXRvcikge1xuXHRcdFx0bGV0IHVzZXJBZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG5cdFx0XHRpZiAodXNlckFnZW50KSB7XG5cdFx0XHRcdHJldHVybiB1c2VyQWdlbnQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAnJztcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBuYXRpdmUgcGxhdGZvcm0gc3RyaW5nIGZyb20gbmF2aWdhdG9yIGlmIGl0IGV4aXN0cy4gSWZcblx0ICogbmF2aWdhdG9yIG9yIG5hdmlnYXRvci5wbGF0Zm9ybSBzdHJpbmcgaXMgbWlzc2luZywgcmV0dXJucyBhbiBlbXB0eVxuXHQgKiBzdHJpbmcuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICogQHByaXZhdGVcblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldE5hdGl2ZVBsYXRmb3JtKCkge1xuXHRcdGxldCBuYXZpZ2F0b3IgPSBVQS5nbG9iYWxzLndpbmRvdyAmJiBVQS5nbG9iYWxzLndpbmRvdy5uYXZpZ2F0b3I7XG5cdFx0aWYgKG5hdmlnYXRvcikge1xuXHRcdFx0bGV0IHBsYXRmb3JtID0gbmF2aWdhdG9yLnBsYXRmb3JtO1xuXHRcdFx0aWYgKHBsYXRmb3JtKSB7XG5cdFx0XHRcdHJldHVybiBwbGF0Zm9ybTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdoZXRoZXIgdGhlIHBsYXRmb3JtIGNvbnRhaW5zIHRoZSBnaXZlbiBzdHJpbmcsIGlnbm9yaW5nIGNhc2UuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByaXZhdGVcblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIG1hdGNoUGxhdGZvcm0oc3RyKSB7XG5cdFx0cmV0dXJuIFVBLnBsYXRmb3JtLmluZGV4T2Yoc3RyKSAhPT0gLTE7XG5cdH1cblxuXHQvKipcblx0ICogV2hldGhlciB0aGUgdXNlciBhZ2VudCBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLCBpZ25vcmluZyBjYXNlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBtYXRjaFVzZXJBZ2VudChzdHIpIHtcblx0XHRyZXR1cm4gVUEudXNlckFnZW50LmluZGV4T2Yoc3RyKSAhPT0gLTE7XG5cdH1cblxuXHQvKipcblx0ICogVGVzdHMgdGhlIHVzZXIgYWdlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB1c2VyQWdlbnQgVGhlIHVzZXIgYWdlbnQgc3RyaW5nLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGxhdGZvcm1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIHRlc3RVc2VyQWdlbnQodXNlckFnZW50ID0gJycsIHBsYXRmb3JtID0gJycpIHtcblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgdXNlciBhZ2VudCB2YWx1ZSBleHRyYWN0ZWQgZnJvbSBicm93c2VyIG5hdGl2ZSB1c2VyIGFnZW50LlxuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLnVzZXJBZ2VudCA9IHVzZXJBZ2VudDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBwbGF0Zm9ybSB2YWx1ZSBleHRyYWN0ZWQgZnJvbSBicm93c2VyIG5hdGl2ZSBwbGF0Zm9ybS5cblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5wbGF0Zm9ybSA9IHBsYXRmb3JtO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIE9TIGlzIE1hYy5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNNYWMgPSBVQS5tYXRjaFBsYXRmb3JtKCdNYWMnKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBPUyBpcyBXaW4uXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzV2luID0gVUEubWF0Y2hQbGF0Zm9ybSgnV2luJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBPcGVyYS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNPcGVyYSA9IFVBLm1hdGNoVXNlckFnZW50KCdPcGVyYScpIHx8IFVBLm1hdGNoVXNlckFnZW50KCdPUFInKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIElFLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc0llID0gVUEubWF0Y2hVc2VyQWdlbnQoJ1RyaWRlbnQnKSB8fCBVQS5tYXRjaFVzZXJBZ2VudCgnTVNJRScpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgRWRnZS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNFZGdlID0gVUEubWF0Y2hVc2VyQWdlbnQoJ0VkZ2UnKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIElFIG9yIEVkZ2UuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzSWVPckVkZ2UgPSBVQS5pc0llIHx8IFVBLmlzRWRnZTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIENocm9tZS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNDaHJvbWUgPVxuXHRcdFx0KFVBLm1hdGNoVXNlckFnZW50KCdDaHJvbWUnKSB8fCBVQS5tYXRjaFVzZXJBZ2VudCgnQ3JpT1MnKSkgJiZcblx0XHRcdCFVQS5pc09wZXJhICYmXG5cdFx0XHQhVUEuaXNFZGdlO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgU2FmYXJpLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc1NhZmFyaSA9XG5cdFx0XHRVQS5tYXRjaFVzZXJBZ2VudCgnU2FmYXJpJykgJiZcblx0XHRcdCEoVUEuaXNDaHJvbWUgfHwgVUEuaXNPcGVyYSB8fCBVQS5pc0VkZ2UpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgRmlyZWZveC5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNGaXJlZm94ID0gVUEubWF0Y2hVc2VyQWdlbnQoJ0ZpcmVmb3gnKTtcblx0fVxufVxuXG4vKipcbiAqIEV4cG9zZXMgZ2xvYmFsIHJlZmVyZW5jZXMuXG4gKiBAdHlwZSB7b2JqZWN0fVxuICogQHN0YXRpY1xuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoVUEsICdnbG9iYWxzJywge1xuXHR3cml0YWJsZTogdHJ1ZSxcblx0dmFsdWU6IHtcblx0XHR3aW5kb3c6IGlzU2VydmVyU2lkZSgpID8gbnVsbCA6IHdpbmRvdyxcblx0fSxcbn0pO1xuXG5VQS50ZXN0VXNlckFnZW50KFVBLmdldE5hdGl2ZVVzZXJBZ2VudCgpLCBVQS5nZXROYXRpdmVQbGF0Zm9ybSgpKTtcblxuZXhwb3J0IGRlZmF1bHQgVUE7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGlzRGVmQW5kTm90TnVsbCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCBBamF4IGZyb20gJ21ldGFsLWFqYXgnO1xuaW1wb3J0IHsgTXVsdGlNYXAgfSBmcm9tICdtZXRhbC1zdHJ1Y3RzJztcbmltcG9ydCBDYW5jZWxsYWJsZVByb21pc2UgZnJvbSAnbWV0YWwtcHJvbWlzZSc7XG5pbXBvcnQgZXJyb3JzIGZyb20gJy4uL2Vycm9ycy9lcnJvcnMnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uL3V0aWxzL3V0aWxzJztcbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgU2NyZWVuIGZyb20gJy4vU2NyZWVuJztcbmltcG9ydCBVcmkgZnJvbSAnbWV0YWwtdXJpJztcbmltcG9ydCBVQSBmcm9tICdtZXRhbC11c2VyYWdlbnQnO1xuXG5jbGFzcyBSZXF1ZXN0U2NyZWVuIGV4dGVuZHMgU2NyZWVuIHtcblxuXHQvKipcblx0ICogUmVxdWVzdCBzY3JlZW4gYWJzdHJhY3QgY2xhc3MgdG8gcGVyZm9ybSBpbyBvcGVyYXRpb25zIG9uIGRlc2NlbmRhbnRcblx0ICogc2NyZWVucy5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqIEBleHRlbmRzIHtTY3JlZW59XG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogQGluaGVyaXREb2Ncblx0XHQgKiBAZGVmYXVsdCB0cnVlXG5cdFx0ICovXG5cdFx0dGhpcy5jYWNoZWFibGUgPSB0cnVlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgZGVmYXVsdCBodHRwIGhlYWRlcnMgdG8gc2V0IG9uIHJlcXVlc3QuXG5cdFx0ICogQHR5cGUgez9PYmplY3Q9fVxuXHRcdCAqIEBkZWZhdWx0IHtcblx0XHQgKiAgICdYLVBKQVgnOiAndHJ1ZScsXG5cdFx0ICogICAnWC1SZXF1ZXN0ZWQtV2l0aCc6ICdYTUxIdHRwUmVxdWVzdCdcblx0XHQgKiB9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaHR0cEhlYWRlcnMgPSB7XG5cdFx0XHQnWC1QSkFYJzogJ3RydWUnLFxuXHRcdFx0J1gtUmVxdWVzdGVkLVdpdGgnOiAnWE1MSHR0cFJlcXVlc3QnXG5cdFx0fTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGRlZmF1bHQgaHR0cCBtZXRob2QgdG8gcGVyZm9ybSB0aGUgcmVxdWVzdC5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBSZXF1ZXN0U2NyZWVuLkdFVFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmh0dHBNZXRob2QgPSBSZXF1ZXN0U2NyZWVuLkdFVDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBYSFIgb2JqZWN0IHJlc3BvbnNpYmxlIGZvciB0aGUgcmVxdWVzdC5cblx0XHQgKiBAdHlwZSB7WE1MSHR0cFJlcXVlc3R9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnJlcXVlc3QgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG5cdFx0ICogQHR5cGUgeyFudW1iZXJ9XG5cdFx0ICogQGRlZmF1bHQgMzAwMDBcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy50aW1lb3V0ID0gMzAwMDA7XG5cdH1cblxuXHQvKipcblx0ICogQXNzZXJ0cyB0aGF0IHJlc3BvbnNlIHN0YXR1cyBjb2RlIGlzIHZhbGlkLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gc3RhdHVzXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGFzc2VydFZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlKHN0YXR1cykge1xuXHRcdGlmICghdGhpcy5pc1ZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlKHN0YXR1cykpIHtcblx0XHRcdHZhciBlcnJvciA9IG5ldyBFcnJvcihlcnJvcnMuSU5WQUxJRF9TVEFUVVMpO1xuXHRcdFx0ZXJyb3IuaW52YWxpZFN0YXR1cyA9IHRydWU7XG5cdFx0XHRlcnJvci5zdGF0dXNDb2RlID0gc3RhdHVzO1xuXHRcdFx0dGhyb3cgZXJyb3I7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRiZWZvcmVVcGRhdGVIaXN0b3J5UGF0aChwYXRoKSB7XG5cdFx0dmFyIHJlZGlyZWN0UGF0aCA9IHRoaXMuZ2V0UmVxdWVzdFBhdGgoKTtcblx0XHRpZiAocmVkaXJlY3RQYXRoICYmIHJlZGlyZWN0UGF0aCAhPT0gcGF0aCkge1xuXHRcdFx0cmV0dXJuIHJlZGlyZWN0UGF0aDtcblx0XHR9XG5cdFx0cmV0dXJuIHBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGJlZm9yZVVwZGF0ZUhpc3RvcnlTdGF0ZShzdGF0ZSkge1xuXHRcdC8vIElmIHN0YXRlIGlzIG91cnMgYW5kIG5hdmlnYXRlIHRvIHBvc3Qtd2l0aG91dC1yZWRpcmVjdC1nZXQgc2V0XG5cdFx0Ly8gaGlzdG9yeSBzdGF0ZSB0byBudWxsLCB0aGF0IHdheSBTZW5uYSB3aWxsIHJlbG9hZCB0aGUgcGFnZSBvblxuXHRcdC8vIHBvcHN0YXRlIHNpbmNlIGl0IGNhbm5vdCBwcmVkaWN0IHBvc3QgZGF0YS5cblx0XHRpZiAoc3RhdGUuc2VubmEgJiYgc3RhdGUuZm9ybSAmJiBzdGF0ZS5yZWRpcmVjdFBhdGggPT09IHN0YXRlLnBhdGgpIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0XHRyZXR1cm4gc3RhdGU7XG5cdH1cblxuXHQvKipcblx0ICogRm9ybWF0cyBsb2FkIHBhdGggYmVmb3JlIGludm9raW5nIGFqYXggY2FsbC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcblx0ICogQHJldHVybiB7c3RyaW5nfSBGb3JtYXR0ZWQgcGF0aDtcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0Zm9ybWF0TG9hZFBhdGgocGF0aCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHBhdGgpO1xuXG5cdFx0dXJpLnNldEhvc3RuYW1lKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhvc3RuYW1lKTtcblx0XHR1cmkuc2V0UHJvdG9jb2woZ2xvYmFscy53aW5kb3cubG9jYXRpb24ucHJvdG9jb2wpO1xuXG5cdFx0aWYgKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnBvcnQpIHtcblx0XHRcdHVyaS5zZXRQb3J0KGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnBvcnQpO1xuXHRcdH1cblxuXHRcdGlmIChVQS5pc0llT3JFZGdlICYmIHRoaXMuaHR0cE1ldGhvZCA9PT0gUmVxdWVzdFNjcmVlbi5HRVQpIHtcblx0XHRcdHJldHVybiB1cmkubWFrZVVuaXF1ZSgpLnRvU3RyaW5nKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVyaS50b1N0cmluZygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGh0dHAgaGVhZGVycy5cblx0ICogQHJldHVybiB7P09iamVjdD19XG5cdCAqL1xuXHRnZXRIdHRwSGVhZGVycygpIHtcblx0XHRyZXR1cm4gdGhpcy5odHRwSGVhZGVycztcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBodHRwIG1ldGhvZC5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldEh0dHBNZXRob2QoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaHR0cE1ldGhvZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHJlcXVlc3QgcGF0aC5cblx0ICogQHJldHVybiB7c3RyaW5nPX1cblx0ICovXG5cdGdldFJlcXVlc3RQYXRoKCkge1xuXHRcdHZhciByZXF1ZXN0ID0gdGhpcy5nZXRSZXF1ZXN0KCk7XG5cdFx0aWYgKHJlcXVlc3QpIHtcblx0XHRcdHZhciByZXF1ZXN0UGF0aCA9IHJlcXVlc3QucmVxdWVzdFBhdGg7XG5cdFx0XHR2YXIgcmVzcG9uc2VVcmwgPSB0aGlzLm1heWJlRXh0cmFjdFJlc3BvbnNlVXJsRnJvbVJlcXVlc3QocmVxdWVzdCk7XG5cdFx0XHRpZiAocmVzcG9uc2VVcmwpIHtcblx0XHRcdFx0cmVxdWVzdFBhdGggPSByZXNwb25zZVVybDtcblx0XHRcdH1cblx0XHRcdGlmIChVQS5pc0llT3JFZGdlICYmIHRoaXMuaHR0cE1ldGhvZCA9PT0gUmVxdWVzdFNjcmVlbi5HRVQpIHtcblx0XHRcdFx0cmVxdWVzdFBhdGggPSBuZXcgVXJpKHJlcXVlc3RQYXRoKS5yZW1vdmVVbmlxdWUoKS50b1N0cmluZygpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHV0aWxzLmdldFVybFBhdGgocmVxdWVzdFBhdGgpO1xuXHRcdH1cblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSByZXF1ZXN0IG9iamVjdC5cblx0ICogQHJldHVybiB7P09iamVjdH1cblx0ICovXG5cdGdldFJlcXVlc3QoKSB7XG5cdFx0cmV0dXJuIHRoaXMucmVxdWVzdDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSByZXF1ZXN0IHRpbWVvdXQuXG5cdCAqIEByZXR1cm4geyFudW1iZXJ9XG5cdCAqL1xuXHRnZXRUaW1lb3V0KCkge1xuXHRcdHJldHVybiB0aGlzLnRpbWVvdXQ7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHJlc3BvbnNlIHN1Y2NlZWRlZC4gQW55IHN0YXR1cyBjb2RlIDJ4eCBvciAzeHggaXMgY29uc2lkZXJlZFxuXHQgKiB2YWxpZC5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXR1c0NvZGVcblx0ICovXG5cdGlzVmFsaWRSZXNwb25zZVN0YXR1c0NvZGUoc3RhdHVzQ29kZSkge1xuXHRcdHJldHVybiBzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDw9IDM5OTtcblx0fVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBmb3JtIGRhdGFcbiAgICogVGhpcyBtZXRob2QgY2FuIGJlIGV4dGVuZGVkIGluIG9yZGVyIHRvIGhhdmUgYSBjdXN0b20gaW1wbGVtZW50YXRpb24gb2YgdGhlIGZvcm0gcGFyYW1zXG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IGZvcm1FbGVtZW50XG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IHN1Ym1pdHRlZEJ1dHRvbkVsZW1lbnRcbiAgICogQHJldHVybiB7IUZvcm1EYXRhfVxuICAgKi9cblx0Z2V0Rm9ybURhdGEoZm9ybUVsZW1lbnQsIHN1Ym1pdHRlZEJ1dHRvbkVsZW1lbnQpIHtcbiAgICBsZXQgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoZm9ybUVsZW1lbnQpO1xuICAgIHRoaXMubWF5YmVBcHBlbmRTdWJtaXRCdXR0b25WYWx1ZV8oZm9ybURhdGEsIHN1Ym1pdHRlZEJ1dHRvbkVsZW1lbnQpO1xuICAgIHJldHVybiBmb3JtRGF0YTtcbiAgfVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0bG9hZChwYXRoKSB7XG5cdFx0Y29uc3QgY2FjaGUgPSB0aGlzLmdldENhY2hlKCk7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChjYWNoZSkpIHtcblx0XHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZShjYWNoZSk7XG5cdFx0fVxuXHRcdGxldCBib2R5ID0gbnVsbDtcblx0XHRsZXQgaHR0cE1ldGhvZCA9IHRoaXMuaHR0cE1ldGhvZDtcblx0XHRjb25zdCBoZWFkZXJzID0gbmV3IE11bHRpTWFwKCk7XG5cdFx0T2JqZWN0LmtleXModGhpcy5odHRwSGVhZGVycykuZm9yRWFjaChoZWFkZXIgPT4gaGVhZGVycy5hZGQoaGVhZGVyLCB0aGlzLmh0dHBIZWFkZXJzW2hlYWRlcl0pKTtcblx0XHRpZiAoZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50KSB7XG5cdFx0XHR0aGlzLmFkZFNhZmFyaVhIUlBvbHlmaWxsKCk7XG5cdFx0XHRib2R5ID0gdGhpcy5nZXRGb3JtRGF0YShnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQsIGdsb2JhbHMuY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudCk7XG5cdFx0XHRodHRwTWV0aG9kID0gUmVxdWVzdFNjcmVlbi5QT1NUO1xuXHRcdFx0aWYgKFVBLmlzSWVPckVkZ2UpIHtcblx0XHRcdFx0aGVhZGVycy5hZGQoJ0lmLU5vbmUtTWF0Y2gnLCAnXCIwXCInKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Y29uc3QgcmVxdWVzdFBhdGggPSB0aGlzLmZvcm1hdExvYWRQYXRoKHBhdGgpO1xuXHRcdHJldHVybiBBamF4XG5cdFx0XHQucmVxdWVzdChyZXF1ZXN0UGF0aCwgaHR0cE1ldGhvZCwgYm9keSwgaGVhZGVycywgbnVsbCwgdGhpcy50aW1lb3V0KVxuXHRcdFx0LnRoZW4oeGhyID0+IHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTYWZhcmlYSFJQb2x5ZmlsbCgpO1xuXHRcdFx0XHR0aGlzLnNldFJlcXVlc3QoeGhyKTtcblx0XHRcdFx0dGhpcy5hc3NlcnRWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZSh4aHIuc3RhdHVzKTtcblx0XHRcdFx0aWYgKGh0dHBNZXRob2QgPT09IFJlcXVlc3RTY3JlZW4uR0VUICYmIHRoaXMuaXNDYWNoZWFibGUoKSkge1xuXHRcdFx0XHRcdHRoaXMuYWRkQ2FjaGUoeGhyLnJlc3BvbnNlVGV4dCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0eGhyLnJlcXVlc3RQYXRoID0gcmVxdWVzdFBhdGg7XG5cdFx0XHRcdHJldHVybiB4aHIucmVzcG9uc2VUZXh0O1xuXHRcdFx0fSlcblx0XHRcdC5jYXRjaCgocmVhc29uKSA9PiB7XG5cdFx0XHRcdHRoaXMucmVtb3ZlU2FmYXJpWEhSUG9seWZpbGwoKTtcblx0XHRcdFx0c3dpdGNoIChyZWFzb24ubWVzc2FnZSkge1xuXHRcdFx0XHRcdGNhc2UgZXJyb3JzLlJFUVVFU1RfVElNRU9VVDpcblx0XHRcdFx0XHRcdHJlYXNvbi50aW1lb3V0ID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgZXJyb3JzLlJFUVVFU1RfRVJST1I6XG5cdFx0XHRcdFx0XHRyZWFzb24ucmVxdWVzdEVycm9yID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgZXJyb3JzLlJFUVVFU1RfUFJFTUFUVVJFX1RFUk1JTkFUSU9OOlxuXHRcdFx0XHRcdFx0cmVhc29uLnJlcXVlc3RFcnJvciA9IHRydWU7XG5cdFx0XHRcdFx0XHRyZWFzb24ucmVxdWVzdFByZW1hdHVyZVRlcm1pbmF0aW9uID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRocm93IHJlYXNvbjtcblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYWRpdGlvbmFsIGRhdGEgdG8gdGhlIGJvZHkgb2YgdGhlIHJlcXVlc3QgaW4gY2FzZSBhIHN1Ym1pdCBidXR0b25cblx0ICogaXMgY2FwdHVyZWQgZHVyaW5nIGZvcm0gc3VibWlzc2lvbi5cblx0ICogQHBhcmFtIHshRm9ybURhdGF9IGJvZHkgVGhlIEZvcm1EYXRhIGNvbnRhaW5pbmcgdGhlIHJlcXVlc3QgYm9keS5cbiAgICogQHBhcmFtIHshRWxlbWVudH0gc3VibWl0dGVkQnV0dG9uRWxlbWVudFxuICAgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXliZUFwcGVuZFN1Ym1pdEJ1dHRvblZhbHVlXyhmb3JtRGF0YSwgc3VibWl0dGVkQnV0dG9uRWxlbWVudCkge1xuXHRcdGlmIChzdWJtaXR0ZWRCdXR0b25FbGVtZW50ICYmIHN1Ym1pdHRlZEJ1dHRvbkVsZW1lbnQubmFtZSkge1xuICAgICAgZm9ybURhdGEuYXBwZW5kKHN1Ym1pdHRlZEJ1dHRvbkVsZW1lbnQubmFtZSwgc3VibWl0dGVkQnV0dG9uRWxlbWVudC52YWx1ZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBmb2xsb3dpbmcgbWV0aG9kIHRyaWVzIHRvIGV4dHJhY3QgdGhlIHJlc3BvbnNlIHVybCB2YWx1ZSBieSBjaGVja2luZ1xuXHQgKiB0aGUgY3VzdG9tIHJlc3BvbnNlIGhlYWRlciAnWC1SZXF1ZXN0LVVSTCcgaWYgcHJvcGVyIHZhbHVlIGlzIG5vdCBwcmVzZW50XG5cdCAqIGluIFhNTEh0dHBSZXF1ZXN0LiBUaGUgdmFsdWUgb2YgcmVzcG9uc2VVUkwgd2lsbCBiZSB0aGUgZmluYWwgVVJMXG5cdCAqIG9idGFpbmVkIGFmdGVyIGFueSByZWRpcmVjdHMuIEludGVybmV0IEV4cGxvcmVyLCBFZGdlIGFuZCBTYWZhcmkgPD0gN1xuXHQgKiBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZmVhdHVyZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlOlxuXHQgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvWE1MSHR0cFJlcXVlc3QvcmVzcG9uc2VVUkxcblx0ICogaHR0cHM6Ly94aHIuc3BlYy53aGF0d2cub3JnLyN0aGUtcmVzcG9uc2V1cmwtYXR0cmlidXRlXG5cdCAqIEBwYXJhbSB7WE1MSHR0cFJlcXVlc3R9IHJlcXVlc3Rcblx0ICogQHJldHVybiB7P3N0cmluZ30gUmVzcG9uc2UgdXJsIGJlc3QgbWF0Y2guXG5cdCAqL1xuXHRtYXliZUV4dHJhY3RSZXNwb25zZVVybEZyb21SZXF1ZXN0KHJlcXVlc3QpIHtcblx0XHR2YXIgcmVzcG9uc2VVcmwgPSByZXF1ZXN0LnJlc3BvbnNlVVJMO1xuXHRcdGlmIChyZXNwb25zZVVybCkge1xuXHRcdFx0cmV0dXJuIHJlc3BvbnNlVXJsO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVxdWVzdC5nZXRSZXNwb25zZUhlYWRlcihSZXF1ZXN0U2NyZWVuLlhfUkVRVUVTVF9VUkxfSEVBREVSKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGlzIGZ1bmN0aW9uIHNldCBhdHRyaWJ1dGUgZGF0YS1zYWZhcmktdGVtcC1kaXNhYmxlZCB0byBcblx0ICogdHJ1ZSBhbmQgc2V0IGRpc2FibGUgYXR0cmlidXRlIG9mIGFuIGlucHV0IHR5cGU9XCJmaWxlXCIgdGFnXG5cdCAqIGlzIHVzZWQgYXMgYSBwb2x5ZmlsbCBmb3IgaU9TIDExLjMgU2FmYXJpIC8gbWFjT1MgU2FmYXJpIDExLjEgXG5cdCAqIGVtcHR5IDxpbnB1dCB0eXBlPVwiZmlsZVwiPiBYSFIgYnVnLlxuXHQgKiBodHRwczovL2dpdGh1Yi5jb20vcmFpbHMvcmFpbHMvaXNzdWVzLzMyNDQwXG5cdCAqIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xODQ0OTBcblx0ICovXG5cdGFkZFNhZmFyaVhIUlBvbHlmaWxsKCkge1xuXHRcdGlmIChnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQgJiYgVUEuaXNTYWZhcmkpIHtcblx0XHRcdGxldCBpbnB1dHMgPSBnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbdHlwZT1cImZpbGVcIl06bm90KFtkaXNhYmxlZF0pJyk7XG5cdFx0XHRmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaW5wdXRzLmxlbmd0aDsgaW5kZXgrKykge1xuXHRcdFx0XHRsZXQgaW5wdXQgPSBpbnB1dHNbaW5kZXhdO1xuXHRcdFx0XHRpZiAoaW5wdXQuZmlsZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHRpbnB1dC5zZXRBdHRyaWJ1dGUoJ2RhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWQnLCAndHJ1ZScpO1xuXHRcdFx0XHRpbnB1dC5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgJycpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUaGlzIGZ1bmN0aW9uIHJlbW92ZSBhdHRyaWJ1dGUgZGF0YS1zYWZhcmktdGVtcC1kaXNhYmxlZCBhbmQgZGlzYWJsZSBhdHRyaWJ1dGVcblx0ICogb2YgYW4gaW5wdXQgdHlwZT1cImZpbGVcIiB0YWcgaXMgdXNlZCBhcyBhIHBvbHlmaWxsIGZvciBpT1MgMTEuMyBTYWZhcmkgLyBtYWNPUyBTYWZhcmkgMTEuMVxuXHQgKiBlbXB0eSA8aW5wdXQgdHlwZT1cImZpbGVcIj4gWEhSIGJ1Zy5cblx0ICogaHR0cHM6Ly9naXRodWIuY29tL3JhaWxzL3JhaWxzL2lzc3Vlcy8zMjQ0MFxuXHQgKiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTg0NDkwXG5cdCAqL1xuXHRyZW1vdmVTYWZhcmlYSFJQb2x5ZmlsbCgpIHtcblx0XHRpZiAoZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50ICYmIFVBLmlzU2FmYXJpKSB7XG5cdFx0XHRsZXQgaW5wdXRzID0gZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9XCJmaWxlXCJdW2RhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWRdJyk7XG5cdFx0XHRmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgaW5wdXRzLmxlbmd0aDsgaW5kZXgrKykge1xuXHRcdFx0XHRjb25zdCBpbnB1dCA9IGlucHV0c1tpbmRleF07XG5cdFx0XHRcdGlucHV0LnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1zYWZhcmktdGVtcC1kaXNhYmxlZCcpO1xuXHRcdFx0XHRpbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGh0dHAgaGVhZGVycy5cblx0ICogQHBhcmFtIHs/T2JqZWN0PX0gaHR0cEhlYWRlcnNcblx0ICovXG5cdHNldEh0dHBIZWFkZXJzKGh0dHBIZWFkZXJzKSB7XG5cdFx0dGhpcy5odHRwSGVhZGVycyA9IGh0dHBIZWFkZXJzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGh0dHAgbWV0aG9kLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGh0dHBNZXRob2Rcblx0ICovXG5cdHNldEh0dHBNZXRob2QoaHR0cE1ldGhvZCkge1xuXHRcdHRoaXMuaHR0cE1ldGhvZCA9IGh0dHBNZXRob2QudG9Mb3dlckNhc2UoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSByZXF1ZXN0IG9iamVjdC5cblx0ICogQHBhcmFtIHs/T2JqZWN0fSByZXF1ZXN0XG5cdCAqL1xuXHRzZXRSZXF1ZXN0KHJlcXVlc3QpIHtcblx0XHR0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG5cdCAqIEBwYXJhbSB7IW51bWJlcn0gdGltZW91dFxuXHQgKi9cblx0c2V0VGltZW91dCh0aW1lb3V0KSB7XG5cdFx0dGhpcy50aW1lb3V0ID0gdGltZW91dDtcblx0fVxuXG59XG5cbi8qKlxuICogSG9sZHMgdmFsdWUgZm9yIG1ldGhvZCBnZXQuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGRlZmF1bHQgJ2dldCdcbiAqIEBzdGF0aWNcbiAqL1xuUmVxdWVzdFNjcmVlbi5HRVQgPSAnZ2V0JztcblxuLyoqXG4gKiBIb2xkcyB2YWx1ZSBmb3IgbWV0aG9kIHBvc3QuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGRlZmF1bHQgJ3Bvc3QnXG4gKiBAc3RhdGljXG4gKi9cblJlcXVlc3RTY3JlZW4uUE9TVCA9ICdwb3N0JztcblxuLyoqXG4gKiBGYWxsYmFjayBodHRwIGhlYWRlciB0byByZXRyaWV2ZSByZXNwb25zZSByZXF1ZXN0IHVybC5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAZGVmYXVsdCAnWC1SZXF1ZXN0LVVSTCdcbiAqIEBzdGF0aWNcbiAqL1xuUmVxdWVzdFNjcmVlbi5YX1JFUVVFU1RfVVJMX0hFQURFUiA9ICdYLVJlcXVlc3QtVVJMJztcblxuZXhwb3J0IGRlZmF1bHQgUmVxdWVzdFNjcmVlbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgYnVpbGRGcmFnbWVudCwgZ2xvYmFsRXZhbCwgZ2xvYmFsRXZhbFN0eWxlcywgbWF0Y2ggfSBmcm9tICdtZXRhbC1kb20nO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgUmVxdWVzdFNjcmVlbiBmcm9tICcuL1JlcXVlc3RTY3JlZW4nO1xuaW1wb3J0IFN1cmZhY2UgZnJvbSAnLi4vc3VyZmFjZS9TdXJmYWNlJztcbmltcG9ydCBVQSBmcm9tICdtZXRhbC11c2VyYWdlbnQnO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uL3V0aWxzL3V0aWxzJztcblxuY2xhc3MgSHRtbFNjcmVlbiBleHRlbmRzIFJlcXVlc3RTY3JlZW4ge1xuXG5cdC8qKlxuXHQgKiBTY3JlZW4gY2xhc3MgdGhhdCBwZXJmb3JtIGEgcmVxdWVzdCBhbmQgZXh0cmFjdHMgc3VyZmFjZSBjb250ZW50cyBmcm9tXG5cdCAqIHRoZSByZXNwb25zZSBjb250ZW50LlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQGV4dGVuZHMge1JlcXVlc3RTY3JlZW59XG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIG1ldGEgc2VsZWN0b3IuIFJlbGV2YW50IHRvIGV4dHJhY3QgPGNvZGU+bWV0YTwvY29kZT4gdGFnc1xuXHRcdCAqIGVsZW1lbnRzIGZyb20gcmVxdWVzdCBmcmFnbWVudHMgdG8gdXNlIGFzIHRoZSBzY3JlZW4uXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgbWV0YVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLm1ldGFUYWdzU2VsZWN0b3IgPSAnbWV0YSc7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgdGl0bGUgc2VsZWN0b3IuIFJlbGV2YW50IHRvIGV4dHJhY3QgdGhlIDxjb2RlPjx0aXRsZT48L2NvZGU+XG5cdFx0ICogZWxlbWVudCBmcm9tIHJlcXVlc3QgZnJhZ21lbnRzIHRvIHVzZSBhcyB0aGUgc2NyZWVuIHRpdGxlLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IHRpdGxlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMudGl0bGVTZWxlY3RvciA9ICd0aXRsZSc7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGFjdGl2YXRlKCkge1xuXHRcdHN1cGVyLmFjdGl2YXRlKCk7XG5cdFx0dGhpcy5yZWxlYXNlVmlydHVhbERvY3VtZW50KCk7XG5cdFx0dGhpcy5wZW5kaW5nU3R5bGVzID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvY2F0ZXMgdmlydHVhbCBkb2N1bWVudCBmb3IgY29udGVudC4gQWZ0ZXIgYWxsb2NhdGVkIHZpcnR1YWwgZG9jdW1lbnRcblx0ICogY2FuIGJlIGFjY2Vzc2VkIGJ5IDxjb2RlPnRoaXMudmlydHVhbERvY3VtZW50PC9jb2RlPi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBodG1sU3RyaW5nXG5cdCAqL1xuXHRhbGxvY2F0ZVZpcnR1YWxEb2N1bWVudEZvckNvbnRlbnQoaHRtbFN0cmluZykge1xuXHRcdGlmICghdGhpcy52aXJ0dWFsRG9jdW1lbnQpIHtcblx0XHRcdHRoaXMudmlydHVhbERvY3VtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdodG1sJyk7XG5cdFx0fVxuXG5cdFx0dGhpcy5jb3B5Tm9kZUF0dHJpYnV0ZXNGcm9tQ29udGVudF8oaHRtbFN0cmluZywgdGhpcy52aXJ0dWFsRG9jdW1lbnQpO1xuXG5cdFx0dGhpcy52aXJ0dWFsRG9jdW1lbnQuaW5uZXJIVE1MID0gaHRtbFN0cmluZztcblx0fVxuXG5cdC8qKlxuXHQgKiBDdXN0b21pemVzIGxvZ2ljIHRvIGFwcGVuZCBzdHlsZXMgaW50byBkb2N1bWVudC4gUmVsZXZhbnQgdG8gd2hlblxuXHQgKiB0cmFja2luZyBhIHN0eWxlIGJ5IGlkIG1ha2Ugc3VyZSB0byByZS1wb3NpdGlvbnMgdGhlIG5ldyBzdHlsZSBpbiB0aGVcblx0ICogc2FtZSBkb20gb3JkZXIuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbmV3U3R5bGVcblx0ICovXG5cdGFwcGVuZFN0eWxlSW50b0RvY3VtZW50XyhuZXdTdHlsZSkge1xuXHRcdHZhciBpc1RlbXBvcmFyeVN0eWxlID0gbWF0Y2gobmV3U3R5bGUsIEh0bWxTY3JlZW4uc2VsZWN0b3JzLnN0eWxlc1RlbXBvcmFyeSk7XG5cdFx0aWYgKGlzVGVtcG9yYXJ5U3R5bGUpIHtcblx0XHRcdHRoaXMucGVuZGluZ1N0eWxlcy5wdXNoKG5ld1N0eWxlKTtcblx0XHR9XG5cdFx0aWYgKG5ld1N0eWxlLmlkKSB7XG5cdFx0XHR2YXIgc3R5bGVJbkRvYyA9IGdsb2JhbHMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobmV3U3R5bGUuaWQpO1xuXHRcdFx0aWYgKHN0eWxlSW5Eb2MpIHtcblx0XHRcdFx0c3R5bGVJbkRvYy5wYXJlbnROb2RlLmluc2VydEJlZm9yZShuZXdTdHlsZSwgc3R5bGVJbkRvYy5uZXh0U2libGluZyk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHR9XG5cdFx0Z2xvYmFscy5kb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG5ld1N0eWxlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBJZiBib2R5IGlzIHVzZWQgYXMgc3VyZmFjZSBmb3JjZXMgdGhlIHJlcXVlc3RlZCBkb2N1bWVudHMgdG8gaGF2ZSBzYW1lIGlkXG5cdCAqIG9mIHRoZSBpbml0aWFsIHBhZ2UuXG5cdCAqL1xuXHRhc3NlcnRTYW1lQm9keUlkSW5WaXJ0dWFsRG9jdW1lbnQoKSB7XG5cdFx0dmFyIGJvZHlTdXJmYWNlID0gdGhpcy52aXJ0dWFsRG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpO1xuXHRcdGlmICghZ2xvYmFscy5kb2N1bWVudC5ib2R5LmlkKSB7XG5cdFx0XHRnbG9iYWxzLmRvY3VtZW50LmJvZHkuaWQgPSAnc2VubmFfc3VyZmFjZV8nICsgZ2V0VWlkKCk7XG5cdFx0fVxuXHRcdGlmIChib2R5U3VyZmFjZSkge1xuXHRcdFx0Ym9keVN1cmZhY2UuaWQgPSBnbG9iYWxzLmRvY3VtZW50LmJvZHkuaWQ7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENvcGllcyBhdHRyaWJ1dGVzIGZyb20gdGhlIDxodG1sPiB0YWcgb2YgY29udGVudCB0byB0aGUgZ2l2ZW4gbm9kZS5cblx0ICovXG5cdGNvcHlOb2RlQXR0cmlidXRlc0Zyb21Db250ZW50Xyhjb250ZW50LCBub2RlKSB7XG5cdFx0Y29udGVudCA9IGNvbnRlbnQucmVwbGFjZSgvWzxdXFxzKmh0bWwvaWcsICc8c2VubmEnKTtcblx0XHRjb250ZW50ID0gY29udGVudC5yZXBsYWNlKC9cXC9odG1sXFxzKlxcPi9pZywgJy9zZW5uYT4nKTtcblx0XHRsZXQgcGxhY2Vob2xkZXI7XG5cdFx0aWYgKFVBLmlzSWUpIHtcblx0XHRcdGNvbnN0IHRlbXBOb2RlID0gZ2xvYmFscy5kb2N1bWVudC5jcmVhdGVSYW5nZSgpLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChjb250ZW50KTtcblx0XHRcdHBsYWNlaG9sZGVyID0gdGVtcE5vZGUucXVlcnlTZWxlY3Rvcignc2VubmEnKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bm9kZS5pbm5lckhUTUwgPSBjb250ZW50O1xuXHRcdFx0cGxhY2Vob2xkZXIgPSBub2RlLnF1ZXJ5U2VsZWN0b3IoJ3Nlbm5hJyk7XG5cdFx0fVxuXG5cdFx0aWYgKHBsYWNlaG9sZGVyKSB7XG5cdFx0XHR1dGlscy5jbGVhck5vZGVBdHRyaWJ1dGVzKG5vZGUpO1xuXHRcdFx0dXRpbHMuY29weU5vZGVBdHRyaWJ1dGVzKHBsYWNlaG9sZGVyLCBub2RlKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQE92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5kaXNwb3NlUGVuZGluZ1N0eWxlcygpO1xuXHRcdHN1cGVyLmRpc3Bvc2VJbnRlcm5hbCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIHBlbmRpbmcgc3R5bGVzIGlmIHNjcmVlbiBnZXQgZGlzcG9zZWQgcHJpb3IgdG8gaXRzIGxvYWRpbmcuXG5cdCAqL1xuXHRkaXNwb3NlUGVuZGluZ1N0eWxlcygpIHtcblx0XHRpZiAodGhpcy5wZW5kaW5nU3R5bGVzKSB7XG5cdFx0XHR1dGlscy5yZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudCh0aGlzLnBlbmRpbmdTdHlsZXMpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBAT3ZlcnJpZGVcblx0ICovXG5cdGV2YWx1YXRlU2NyaXB0cyhzdXJmYWNlcykge1xuXHRcdHZhciBldmFsdWF0ZVRyYWNrZWRTY3JpcHRzID0gdGhpcy5ldmFsdWF0ZVRyYWNrZWRSZXNvdXJjZXNfKFxuXHRcdFx0Z2xvYmFsRXZhbC5ydW5TY3JpcHRzSW5FbGVtZW50LCBIdG1sU2NyZWVuLnNlbGVjdG9ycy5zY3JpcHRzLFxuXHRcdFx0SHRtbFNjcmVlbi5zZWxlY3RvcnMuc2NyaXB0c1RlbXBvcmFyeSwgSHRtbFNjcmVlbi5zZWxlY3RvcnMuc2NyaXB0c1Blcm1hbmVudCk7XG5cblx0XHRyZXR1cm4gZXZhbHVhdGVUcmFja2VkU2NyaXB0cy50aGVuKCgpID0+IHN1cGVyLmV2YWx1YXRlU2NyaXB0cyhzdXJmYWNlcykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBPdmVycmlkZVxuXHQgKi9cblx0ZXZhbHVhdGVTdHlsZXMoc3VyZmFjZXMpIHtcblx0XHR0aGlzLnBlbmRpbmdTdHlsZXMgPSBbXTtcblx0XHR2YXIgZXZhbHVhdGVUcmFja2VkU3R5bGVzID0gdGhpcy5ldmFsdWF0ZVRyYWNrZWRSZXNvdXJjZXNfKFxuXHRcdFx0Z2xvYmFsRXZhbFN0eWxlcy5ydW5TdHlsZXNJbkVsZW1lbnQsIEh0bWxTY3JlZW4uc2VsZWN0b3JzLnN0eWxlcyxcblx0XHRcdEh0bWxTY3JlZW4uc2VsZWN0b3JzLnN0eWxlc1RlbXBvcmFyeSwgSHRtbFNjcmVlbi5zZWxlY3RvcnMuc3R5bGVzUGVybWFuZW50LFxuXHRcdFx0dGhpcy5hcHBlbmRTdHlsZUludG9Eb2N1bWVudF8uYmluZCh0aGlzKSk7XG5cblx0XHRyZXR1cm4gZXZhbHVhdGVUcmFja2VkU3R5bGVzLnRoZW4oKCkgPT4gc3VwZXIuZXZhbHVhdGVTdHlsZXMoc3VyZmFjZXMpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gZXZhbHVhdGUgdGhlIGZhdmljb24gc3R5bGUgYmVmb3JlIHRoZSBzY3JlZW4gYmVjb21lcyB2aXNpYmxlLlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9XG5cdCAqL1xuXHRldmFsdWF0ZUZhdmljb25fKCkge1xuXHRcdGNvbnN0IHJlc291cmNlc0luVmlydHVhbCA9IHRoaXMudmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfKEh0bWxTY3JlZW4uc2VsZWN0b3JzLmZhdmljb24pO1xuXHRcdGNvbnN0IHJlc291cmNlc0luRG9jdW1lbnQgPSB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxfKEh0bWxTY3JlZW4uc2VsZWN0b3JzLmZhdmljb24pO1xuXG5cdFx0cmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUpID0+IHtcblx0XHRcdHV0aWxzLnJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50KHJlc291cmNlc0luRG9jdW1lbnQpO1xuXHRcdFx0dGhpcy5ydW5GYXZpY29uSW5FbGVtZW50XyhyZXNvdXJjZXNJblZpcnR1YWwpLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdHJhY2tlZCByZXNvdXJjZXMgaW5zaWRlIGluY29taW5nIGZyYWdtZW50IGFuZCByZW1vdmUgZXhpc3Rpbmdcblx0ICogdGVtcG9yYXJ5IHJlc291cmNlcy5cblx0ICogQHBhcmFtIHs/ZnVuY3Rpb24oKX0gYXBwZW5kRm4gRnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlIGludG8gZG9jdW1lbnQuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2VsZWN0b3IgU2VsZWN0b3IgdXNlZCB0byBmaW5kIHJlc291cmNlcyB0byB0cmFjay5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzZWxlY3RvclRlbXBvcmFyeSBTZWxlY3RvciB1c2VkIHRvIGZpbmQgdGVtcG9yYXJ5XG5cdCAqICAgICByZXNvdXJjZXMgdG8gdHJhY2suXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2VsZWN0b3JQZXJtYW5lbnQgU2VsZWN0b3IgdXNlZCB0byBmaW5kIHBlcm1hbmVudFxuXHQgKiAgICAgcmVzb3VyY2VzIHRvIHRyYWNrLlxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbn0gb3B0X2FwcGVuZFJlc291cmNlRm4gT3B0aW9uYWwgZnVuY3Rpb24gdXNlZCB0b1xuXHQgKiAgICAgZXZhbHVhdGUgZnJhZ21lbnQgY29udGFpbmluZyByZXNvdXJjZXMuXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gRGVmZXJyZWQgdGhhdCB3YWl0cyByZXNvdXJjZXMgZXZhbHVhdGlvbiB0b1xuXHQgKiAgICAgY29tcGxldGUuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRldmFsdWF0ZVRyYWNrZWRSZXNvdXJjZXNfKGV2YWx1YXRvckZuLCBzZWxlY3Rvciwgc2VsZWN0b3JUZW1wb3JhcnksIHNlbGVjdG9yUGVybWFuZW50LCBvcHRfYXBwZW5kUmVzb3VyY2VGbikge1xuXHRcdHZhciB0cmFja2VkID0gdGhpcy52aXJ0dWFsUXVlcnlTZWxlY3RvckFsbF8oc2VsZWN0b3IpO1xuXHRcdHZhciB0ZW1wb3Jhcmllc0luRG9jID0gdGhpcy5xdWVyeVNlbGVjdG9yQWxsXyhzZWxlY3RvclRlbXBvcmFyeSk7XG5cdFx0dmFyIHBlcm1hbmVudHNJbkRvYyA9IHRoaXMucXVlcnlTZWxlY3RvckFsbF8oc2VsZWN0b3JQZXJtYW5lbnQpO1xuXG5cdFx0Ly8gQWRkcyBwZXJtYW5lbnQgcmVzb3VyY2VzIGluIGRvY3VtZW50IHRvIGNhY2hlLlxuXHRcdHBlcm1hbmVudHNJbkRvYy5mb3JFYWNoKChyZXNvdXJjZSkgPT4ge1xuXHRcdFx0dmFyIHJlc291cmNlS2V5ID0gdGhpcy5nZXRSZXNvdXJjZUtleV8ocmVzb3VyY2UpO1xuXHRcdFx0aWYgKHJlc291cmNlS2V5KSB7XG5cdFx0XHRcdEh0bWxTY3JlZW4ucGVybWFuZW50UmVzb3VyY2VzSW5Eb2NbcmVzb3VyY2VLZXldID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHZhciBmcmFnID0gYnVpbGRGcmFnbWVudCgpO1xuXHRcdHRyYWNrZWQuZm9yRWFjaCgocmVzb3VyY2UpID0+IHtcblx0XHRcdHZhciByZXNvdXJjZUtleSA9IHRoaXMuZ2V0UmVzb3VyY2VLZXlfKHJlc291cmNlKTtcblx0XHRcdC8vIERvIG5vdCBsb2FkIHBlcm1hbmVudCByZXNvdXJjZXMgaWYgYWxyZWFkeSBpbiBkb2N1bWVudC5cblx0XHRcdGlmICghSHRtbFNjcmVlbi5wZXJtYW5lbnRSZXNvdXJjZXNJbkRvY1tyZXNvdXJjZUtleV0pIHtcblx0XHRcdFx0ZnJhZy5hcHBlbmRDaGlsZChyZXNvdXJjZSk7XG5cdFx0XHR9XG5cdFx0XHQvLyBJZiByZXNvdXJjZSBoYXMga2V5IGFuZCBpcyBwZXJtYW5lbnQgYWRkIHRvIGNhY2hlLlxuXHRcdFx0aWYgKHJlc291cmNlS2V5ICYmIG1hdGNoKHJlc291cmNlLCBzZWxlY3RvclBlcm1hbmVudCkpIHtcblx0XHRcdFx0SHRtbFNjcmVlbi5wZXJtYW5lbnRSZXNvdXJjZXNJbkRvY1tyZXNvdXJjZUtleV0gPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoKHJlc29sdmUpID0+IHtcblx0XHRcdGV2YWx1YXRvckZuKGZyYWcsICgpID0+IHtcblx0XHRcdFx0dXRpbHMucmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQodGVtcG9yYXJpZXNJbkRvYyk7XG5cdFx0XHRcdHJlc29sdmUoKTtcblx0XHRcdH0sIG9wdF9hcHBlbmRSZXNvdXJjZUZuKTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAT3ZlcnJpZGVcblx0ICovXG5cdGZsaXAoc3VyZmFjZXMpIHtcblx0XHRyZXR1cm4gc3VwZXIuZmxpcChzdXJmYWNlcykudGhlbigoKSA9PiB7XG5cdFx0XHR1dGlscy5jbGVhck5vZGVBdHRyaWJ1dGVzKGdsb2JhbHMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KTtcblx0XHRcdHV0aWxzLmNvcHlOb2RlQXR0cmlidXRlcyh0aGlzLnZpcnR1YWxEb2N1bWVudCwgZ2xvYmFscy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpO1xuXHRcdFx0dGhpcy5ldmFsdWF0ZUZhdmljb25fKCk7XG5cdFx0XHR0aGlzLnVwZGF0ZU1ldGFUYWdzXygpO1xuXHRcdH0pO1xuXHR9XG5cblx0dXBkYXRlTWV0YVRhZ3NfKCkge1xuXHRcdGNvbnN0IGN1cnJlbnRNZXRhTm9kZXMgPSB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxfKCdtZXRhJyk7XG5cdFx0Y29uc3QgbWV0YXNGcm9tVmlydHVhbERvY3VtZW50ID0gdGhpcy5tZXRhcztcblx0XHRpZiAoY3VycmVudE1ldGFOb2Rlcykge1xuXHRcdFx0dXRpbHMucmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQoY3VycmVudE1ldGFOb2Rlcyk7XG5cdFx0XHRpZiAobWV0YXNGcm9tVmlydHVhbERvY3VtZW50KSB7XG5cdFx0XHRcdG1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudC5mb3JFYWNoKChtZXRhKSA9PiBnbG9iYWxzLmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQobWV0YSkpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyBhIGtleSB0byBpZGVudGlmeSB0aGUgcmVzb3VyY2UgYmFzZWQgb24gaXRzIGF0dHJpYnV0ZXMuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gcmVzb3VyY2Vcblx0ICogQHJldHVybiB7c3RyaW5nfSBFeHRyYWN0ZWQga2V5IGJhc2VkIG9uIHJlc291cmNlIGF0dHJpYnV0ZXMgaW4gb3JkZXIgb2Zcblx0ICogICAgIHByZWZlcmVuY2U6IGlkLCBocmVmLCBzcmMuXG5cdCAqL1xuXHRnZXRSZXNvdXJjZUtleV8ocmVzb3VyY2UpIHtcblx0XHRyZXR1cm4gcmVzb3VyY2UuaWQgfHwgcmVzb3VyY2UuaHJlZiB8fCByZXNvdXJjZS5zcmMgfHwgJyc7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGdldFN1cmZhY2VDb250ZW50KHN1cmZhY2VJZCkge1xuXHRcdHZhciBzdXJmYWNlID0gdGhpcy52aXJ0dWFsRG9jdW1lbnQucXVlcnlTZWxlY3RvcignIycgKyBzdXJmYWNlSWQpO1xuXHRcdGlmIChzdXJmYWNlKSB7XG5cdFx0XHR2YXIgZGVmYXVsdENoaWxkID0gc3VyZmFjZS5xdWVyeVNlbGVjdG9yKCcjJyArIHN1cmZhY2VJZCArICctJyArIFN1cmZhY2UuREVGQVVMVCk7XG5cdFx0XHRpZiAoZGVmYXVsdENoaWxkKSB7XG5cdFx0XHRcdHJldHVybiBkZWZhdWx0Q2hpbGQuaW5uZXJIVE1MO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHN1cmZhY2UuaW5uZXJIVE1MOyAvLyBJZiBkZWZhdWx0IGNvbnRlbnQgbm90IGZvdW5kLCB1c2Ugc3VyZmFjZSBjb250ZW50XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHRpdGxlIHNlbGVjdG9yLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0VGl0bGVTZWxlY3RvcigpIHtcblx0XHRyZXR1cm4gdGhpcy50aXRsZVNlbGVjdG9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRsb2FkKHBhdGgpIHtcblx0XHRyZXR1cm4gc3VwZXIubG9hZChwYXRoKVxuXHRcdFx0LnRoZW4oY29udGVudCA9PiB7XG5cdFx0XHRcdHRoaXMuYWxsb2NhdGVWaXJ0dWFsRG9jdW1lbnRGb3JDb250ZW50KGNvbnRlbnQpO1xuXHRcdFx0XHR0aGlzLnJlc29sdmVUaXRsZUZyb21WaXJ0dWFsRG9jdW1lbnQoKTtcblx0XHRcdFx0dGhpcy5yZXNvbHZlTWV0YVRhZ3NGcm9tVmlydHVhbERvY3VtZW50KCk7XG5cdFx0XHRcdHRoaXMuYXNzZXJ0U2FtZUJvZHlJZEluVmlydHVhbERvY3VtZW50KCk7XG5cdFx0XHRcdGlmIChVQS5pc0llKSB7XG5cdFx0XHRcdFx0dGhpcy5tYWtlVGVtcG9yYXJ5U3R5bGVzSHJlZnNVbmlxdWVfKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbnRlbnQ7XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBRdWVyaWVzIHRlbXBvcmFyeSBzdHlsZXMgZnJvbSB2aXJ0dWFsIGRvY3VtZW50LCBhbmQgbWFrZXMgdGhlbSB1bmlxdWUuXG5cdCAqIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciBjYWNoaW5nIGFuZCBsb2FkIGV2ZW50IGZpcmluZyBpc3N1ZXMgc3BlY2lmaWMgdG9cblx0ICogSUUxMS4gaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9lbi11cy9taWNyb3NvZnQtZWRnZS9wbGF0Zm9ybS9pc3N1ZXMvNzk0MDE3MS9cblx0ICovXG5cdG1ha2VUZW1wb3JhcnlTdHlsZXNIcmVmc1VuaXF1ZV8oKSB7XG5cdFx0dmFyIHRlbXBvcmFyaWVzSW5Eb2MgPSB0aGlzLnZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyhIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXNUZW1wb3JhcnkpO1xuXHRcdHRlbXBvcmFyaWVzSW5Eb2MuZm9yRWFjaCgoc3R5bGUpID0+IHRoaXMucmVwbGFjZVN0eWxlQW5kTWFrZVVuaXF1ZV8oc3R5bGUpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IGVsZW1lbnQgZnJvbSBnaXZlbiwgY29waWVzIGF0dHJpYnV0ZXMsIG11dGF0ZXMgaHJlZiB0byBiZVxuXHQgKiB1bmlxdWUgdG8gcHJldmVudCBjYWNoaW5nIGFuZCBtb3JlIHRoYW4gb25lIGxvYWQvZXJyb3IgZXZlbnQgZnJvbSBmaXJpbmcuXG5cdCAqL1xuXHRyZXBsYWNlU3R5bGVBbmRNYWtlVW5pcXVlXyhzdHlsZSkge1xuXHRcdGlmIChzdHlsZS5ocmVmKSB7XG5cdFx0XHR2YXIgbmV3U3R5bGUgPSBnbG9iYWxzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoc3R5bGUudGFnTmFtZSk7XG5cdFx0XHRzdHlsZS5ocmVmID0gbmV3IFVyaShzdHlsZS5ocmVmKS5tYWtlVW5pcXVlKCkudG9TdHJpbmcoKTtcblx0XHRcdHV0aWxzLmNvcHlOb2RlQXR0cmlidXRlcyhzdHlsZSwgbmV3U3R5bGUpO1xuXHRcdFx0c3R5bGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobmV3U3R5bGUsIHN0eWxlKTtcblx0XHRcdHN0eWxlLmRpc2FibGVkID0gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB0aGUgZmF2aWNvbiBlbGVtZW50cyB0byB0aGUgZG9jdW1lbnQuXG5cdCAqIEBwYXJhbSB7IUFycmF5PEVsZW1lbnQ+fSBlbGVtZW50c1xuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9XG5cdCAqL1xuXHRydW5GYXZpY29uSW5FbGVtZW50XyhlbGVtZW50cykge1xuXHRcdHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdFx0XHRlbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKFxuXHRcdFx0XHRVQS5pc0llID8gZWxlbWVudCA6IHV0aWxzLnNldEVsZW1lbnRXaXRoUmFuZG9tSHJlZihlbGVtZW50KVxuXHRcdFx0KSk7XG5cdFx0XHRyZXNvbHZlKCk7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUXVlcmllcyBlbGVtZW50cyBmcm9tIHZpcnR1YWwgZG9jdW1lbnQgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgZWxlbWVudHMuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2VsZWN0b3Jcblx0ICogQHJldHVybiB7YXJyYXkuPEVsZW1lbnQ+fVxuXHQgKi9cblx0dmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMudmlydHVhbERvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBRdWVyaWVzIGVsZW1lbnRzIGZyb20gZG9jdW1lbnQgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgZWxlbWVudHMuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2VsZWN0b3Jcblx0ICogQHJldHVybiB7YXJyYXkuPEVsZW1lbnQ+fVxuXHQgKi9cblx0cXVlcnlTZWxlY3RvckFsbF8oc2VsZWN0b3IpIHtcblx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZ2xvYmFscy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVsZWFzZXMgdmlydHVhbCBkb2N1bWVudCBhbGxvY2F0ZWQgZm9yIGNvbnRlbnQuXG5cdCAqL1xuXHRyZWxlYXNlVmlydHVhbERvY3VtZW50KCkge1xuXHRcdHRoaXMudmlydHVhbERvY3VtZW50ID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXNvbHZlcyB0aXRsZSBmcm9tIGFsbG9jYXRlZCB2aXJ0dWFsIGRvY3VtZW50LlxuXHQgKi9cblx0cmVzb2x2ZVRpdGxlRnJvbVZpcnR1YWxEb2N1bWVudCgpIHtcblx0XHRjb25zdCB0aXRsZSA9IHRoaXMudmlydHVhbERvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy50aXRsZVNlbGVjdG9yKTtcblx0XHRpZiAodGl0bGUpIHtcblx0XHRcdHRoaXMuc2V0VGl0bGUodGl0bGUudGV4dENvbnRlbnQudHJpbSgpKTtcblx0XHR9XG5cdH1cblxuXHRyZXNvbHZlTWV0YVRhZ3NGcm9tVmlydHVhbERvY3VtZW50KCkge1xuXHRcdGNvbnN0IG1ldGFzID0gdGhpcy52aXJ0dWFsUXVlcnlTZWxlY3RvckFsbF8odGhpcy5tZXRhVGFnc1NlbGVjdG9yKTtcblx0XHRpZiAobWV0YXMpIHtcblx0XHRcdHRoaXMuc2V0TWV0YXMobWV0YXMpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSB0aXRsZSBzZWxlY3Rvci5cblx0ICogQHBhcmFtIHshc3RyaW5nfSB0aXRsZVNlbGVjdG9yXG5cdCAqL1xuXHRzZXRUaXRsZVNlbGVjdG9yKHRpdGxlU2VsZWN0b3IpIHtcblx0XHR0aGlzLnRpdGxlU2VsZWN0b3IgPSB0aXRsZVNlbGVjdG9yO1xuXHR9XG5cbn1cblxuLyoqXG4gKiBIZWxwZXIgc2VsZWN0b3IgZm9yIGlnbm9yZSBmYXZpY29uIHdoZW4gZXhpc3QgZGF0YS1zZW5uYS10cmFjay5cbiAqL1xuY29uc3QgaWdub3JlRmF2aWNvbiA9ICc6bm90KFtyZWw9XCJTaG9ydGN1dCBJY29uXCJdKTpub3QoW3JlbD1cInNob3J0Y3V0IGljb25cIl0pOm5vdChbcmVsPVwiaWNvblwiXSk6bm90KFtocmVmJD1cImZhdmljb24uaWNvblwiXSknO1xuXG4vKipcbiAqIEhlbHBlciBzZWxlY3RvcnMgZm9yIHRyYWNraW5nIHJlc291cmNlcy5cbiAqIEB0eXBlIHtvYmplY3R9XG4gKiBAcHJvdGVjdGVkXG4gKiBAc3RhdGljXG4gKi9cbkh0bWxTY3JlZW4uc2VsZWN0b3JzID0ge1xuXHRmYXZpY29uOiAnbGlua1tyZWw9XCJTaG9ydGN1dCBJY29uXCJdLGxpbmtbcmVsPVwic2hvcnRjdXQgaWNvblwiXSxsaW5rW3JlbD1cImljb25cIl0sbGlua1tocmVmJD1cImZhdmljb24uaWNvblwiXScsXG5cdHNjcmlwdHM6ICdzY3JpcHRbZGF0YS1zZW5uYS10cmFja10nLFxuXHRzY3JpcHRzUGVybWFuZW50OiAnc2NyaXB0W2RhdGEtc2VubmEtdHJhY2s9XCJwZXJtYW5lbnRcIl0nLFxuXHRzY3JpcHRzVGVtcG9yYXJ5OiAnc2NyaXB0W2RhdGEtc2VubmEtdHJhY2s9XCJ0ZW1wb3JhcnlcIl0nLFxuXHRzdHlsZXM6IGBzdHlsZVtkYXRhLXNlbm5hLXRyYWNrXSxsaW5rW2RhdGEtc2VubmEtdHJhY2tdJHtpZ25vcmVGYXZpY29ufWAsXG5cdHN0eWxlc1Blcm1hbmVudDogYHN0eWxlW2RhdGEtc2VubmEtdHJhY2s9XCJwZXJtYW5lbnRcIl0sbGlua1tkYXRhLXNlbm5hLXRyYWNrPVwicGVybWFuZW50XCJdJHtpZ25vcmVGYXZpY29ufWAsXG5cdHN0eWxlc1RlbXBvcmFyeTogYHN0eWxlW2RhdGEtc2VubmEtdHJhY2s9XCJ0ZW1wb3JhcnlcIl0sbGlua1tkYXRhLXNlbm5hLXRyYWNrPVwidGVtcG9yYXJ5XCJdJHtpZ25vcmVGYXZpY29ufWBcbn07XG5cbi8qKlxuICogQ2FjaGVzIHBlcm1hbmVudCByZXNvdXJjZSBrZXlzLlxuICogQHR5cGUge29iamVjdH1cbiAqIEBwcm90ZWN0ZWRcbiAqIEBzdGF0aWNcbiAqL1xuSHRtbFNjcmVlbi5wZXJtYW5lbnRSZXNvdXJjZXNJbkRvYyA9IHt9O1xuXG5leHBvcnQgZGVmYXVsdCBIdG1sU2NyZWVuO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBEaXNwb3NhYmxlLCBnZXRVaWQsIGlzRGVmQW5kTm90TnVsbCwgaXNFbGVtZW50LCBvYmplY3QgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgZGF0YUF0dHJpYnV0ZXMgZnJvbSAnLi9kYXRhQXR0cmlidXRlcyc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IEFwcCBmcm9tICcuL0FwcCc7XG5pbXBvcnQgSHRtbFNjcmVlbiBmcm9tICcuLi9zY3JlZW4vSHRtbFNjcmVlbic7XG5pbXBvcnQgUm91dGUgZnJvbSAnLi4vcm91dGUvUm91dGUnO1xuXG5jbGFzcyBBcHBEYXRhQXR0cmlidXRlSGFuZGxlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXG5cdC8qKlxuXHQgKiBJbml0aWxpemVzIEFwcCwgcmVnaXN0ZXIgc3VyZmFjZXMgYW5kIHJvdXRlcyBmcm9tIGRhdGEgYXR0cmlidXRlcy5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGFwcCByZWZlcmVuY2UgaW5pdGlhbGl6ZWQgYnkgZGF0YSBhdHRyaWJ1dGVzLlxuXHRcdCAqIEB0eXBlIHtBcHB9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqL1xuXHRcdHRoaXMuYXBwID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBiYXNlIGVsZW1lbnQgdG8gc2VhcmNoIGluaXRpYWxpemF0aW9uIGRhdGEgYXR0cmlidXRlcy4gVGhpc1xuXHRcdCAqIGVsZW1lbnQgaXMgdGhlIGNvbnRhaW5lciB1c2VkIHRvIGVuYWJsZSBpbml0aWFsaXphdGlvbiBiYXNlZCBvbiB0aGVcblx0XHQgKiBwcmVzZW5jZSBvZiBgZGF0YS1zZW5uYWAgYXR0cmlidXRlLlxuXHRcdCAqIEB0eXBlIHtFbGVtZW50fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKi9cblx0XHR0aGlzLmJhc2VFbGVtZW50ID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBJbml0cyBhcHBsaWNhdGlvbiBiYXNlZCBvbiBpbmZvcm1hdGlvbiBzY2FubmVkIGZyb20gZG9jdW1lbnQuXG5cdCAqL1xuXHRoYW5kbGUoKSB7XG5cdFx0aWYgKCFpc0VsZW1lbnQodGhpcy5iYXNlRWxlbWVudCkpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignU2VubmEgZGF0YSBhdHRyaWJ1dGUgaGFuZGxlciBiYXNlIGVsZW1lbnQgJyArXG5cdFx0XHRcdCdub3Qgc2V0IG9yIGludmFsaWQsIHRyeSBzZXR0aW5nIGEgdmFsaWQgZWxlbWVudCB0aGF0ICcgK1xuXHRcdFx0XHQnY29udGFpbnMgYSBgZGF0YS1zZW5uYWAgYXR0cmlidXRlLicpO1xuXHRcdH1cblxuXHRcdGlmICghdGhpcy5iYXNlRWxlbWVudC5oYXNBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMuc2VubmEpKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgd2FzIG5vdCBpbml0aWFsaXplZCBmcm9tIGRhdGEgYXR0cmlidXRlcy4gJyArXG5cdFx0XHRcdCdJbiBvcmRlciB0byBlbmFibGUgaXRzIHVzYWdlIGZyb20gZGF0YSBhdHRyaWJ1dGVzIHRyeSBzZXR0aW5nICcgK1xuXHRcdFx0XHQnaW4gdGhlIGJhc2UgZWxlbWVudCwgZS5nLiBgPGJvZHkgZGF0YS1zZW5uYT5gLicpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmFwcCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdTZW5uYSBhcHAgd2FzIGFscmVhZHkgaW5pdGlhbGl6ZWQuJyk7XG5cdFx0fVxuXG5cdFx0Y29uc29sZS5sb2coJ1Nlbm5hIGluaXRpYWxpemVkIGZyb20gZGF0YSBhdHRyaWJ1dGUuJyk7XG5cblx0XHR0aGlzLmFwcCA9IG5ldyBBcHAoKTtcblx0XHR0aGlzLm1heWJlQWRkUm91dGVzXygpO1xuXHRcdHRoaXMubWF5YmVBZGRTdXJmYWNlc18oKTtcblx0XHR0aGlzLm1heWJlU2V0QmFzZVBhdGhfKCk7XG5cdFx0dGhpcy5tYXliZVNldExpbmtTZWxlY3Rvcl8oKTtcblx0XHR0aGlzLm1heWJlU2V0TG9hZGluZ0Nzc0NsYXNzXygpO1xuXHRcdHRoaXMubWF5YmVTZXRVcGRhdGVTY3JvbGxQb3NpdGlvbl8oKTtcblx0XHR0aGlzLm1heWJlRGlzcGF0Y2hfKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHRpZiAodGhpcy5hcHApIHtcblx0XHRcdHRoaXMuYXBwLmRpc3Bvc2UoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgYXBwIHJlZmVyZW5jZS5cblx0ICogQHJldHVybiB7QXBwfVxuXHQgKi9cblx0Z2V0QXBwKCkge1xuXHRcdHJldHVybiB0aGlzLmFwcDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBiYXNlIGVsZW1lbnQuXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9IGJhc2VFbGVtZW50XG5cdCAqL1xuXHRnZXRCYXNlRWxlbWVudCgpIHtcblx0XHRyZXR1cm4gdGhpcy5iYXNlRWxlbWVudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBhZGRzIGFwcCByb3V0ZXMgZnJvbSBsaW5rIGVsZW1lbnRzIHRoYXQgYXJlIGBzZW5uYS1yb3V0ZWAuXG5cdCAqL1xuXHRtYXliZUFkZFJvdXRlc18oKSB7XG5cdFx0dmFyIHJvdXRlc1NlbGVjdG9yID0gJ2xpbmtbcmVsPVwic2VubmEtcm91dGVcIl0nO1xuXHRcdHRoaXMucXVlcnlTZWxlY3RvckFsbEFzQXJyYXlfKHJvdXRlc1NlbGVjdG9yKS5mb3JFYWNoKChsaW5rKSA9PiB0aGlzLm1heWJlUGFyc2VMaW5rUm91dGVfKGxpbmspKTtcblx0XHRpZiAoIXRoaXMuYXBwLmhhc1JvdXRlcygpKSB7XG5cdFx0XHR0aGlzLmFwcC5hZGRSb3V0ZXMobmV3IFJvdXRlKC8uKi8sIEh0bWxTY3JlZW4pKTtcblx0XHRcdGNvbnNvbGUubG9nKCdTZW5uYSBjYW5cXCd0IGZpbmQgcm91dGUgZWxlbWVudHMsIGFkZGluZyBkZWZhdWx0LicpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBhZGRzIGFwcCBzdXJmYWNlcyBieSBzY2FubmluZyBgZGF0YS1zZW5uYS1zdXJmYWNlYCBkYXRhIGF0dHJpYnV0ZS5cblx0ICovXG5cdG1heWJlQWRkU3VyZmFjZXNfKCkge1xuXHRcdHZhciBzdXJmYWNlc1NlbGVjdG9yID0gJ1snICsgZGF0YUF0dHJpYnV0ZXMuc3VyZmFjZSArICddJztcblx0XHR0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxBc0FycmF5XyhzdXJmYWNlc1NlbGVjdG9yKS5mb3JFYWNoKChzdXJmYWNlRWxlbWVudCkgPT4ge1xuXHRcdFx0dGhpcy51cGRhdGVFbGVtZW50SWRJZlNwZWNpYWxTdXJmYWNlXyhzdXJmYWNlRWxlbWVudCk7XG5cdFx0XHR0aGlzLmFwcC5hZGRTdXJmYWNlcyhzdXJmYWNlRWxlbWVudC5pZCk7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcGF0Y2hlcyBhcHAgbmF2aWdhdGlvbiB0byB0aGUgY3VycmVudCBwYXRoIHdoZW4gaW5pdGlhbGl6ZXMuXG5cdCAqL1xuXHRtYXliZURpc3BhdGNoXygpIHtcblx0XHRpZiAodGhpcy5iYXNlRWxlbWVudC5oYXNBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMuZGlzcGF0Y2gpKSB7XG5cdFx0XHR0aGlzLmFwcC5kaXNwYXRjaCgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGFwcCByb3V0ZSBieSBwYXJzaW5nIHZhbGlkIGxpbmsgZWxlbWVudHMuIEEgdmFsaWQgbGluayBlbGVtZW50IGlzIG9mXG5cdCAqIHRoZSBraW5kIGByZWw9XCJzZW5uYS1yb3V0ZVwiYC5cblx0ICogQHBhcmFtIHtFbGVtZW50fSBsaW5rXG5cdCAqL1xuXHRtYXliZVBhcnNlTGlua1JvdXRlXyhsaW5rKSB7XG5cdFx0dmFyIHJvdXRlID0gbmV3IFJvdXRlKHRoaXMubWF5YmVQYXJzZUxpbmtSb3V0ZVBhdGhfKGxpbmspLCB0aGlzLm1heWJlUGFyc2VMaW5rUm91dGVIYW5kbGVyXyhsaW5rKSk7XG5cdFx0dGhpcy5hcHAuYWRkUm91dGVzKHJvdXRlKTtcblx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCByb3V0ZSAnICsgcm91dGUuZ2V0UGF0aCgpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBwYXJzZSBsaW5rIHJvdXRlIGhhbmRsZXIuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGlua1xuXHQgKiBAcmV0dXJuIHs/c3RyaW5nfVxuXHQgKi9cblx0bWF5YmVQYXJzZUxpbmtSb3V0ZUhhbmRsZXJfKGxpbmspIHtcblx0XHR2YXIgaGFuZGxlciA9IGxpbmsuZ2V0QXR0cmlidXRlKCd0eXBlJyk7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChoYW5kbGVyKSkge1xuXHRcdFx0aGFuZGxlciA9IG9iamVjdC5nZXRPYmplY3RCeU5hbWUoaGFuZGxlcik7XG5cdFx0fVxuXHRcdHJldHVybiBoYW5kbGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHBhcnNlIGxpbmsgcm91dGUgcGF0aC5cblx0ICogQHBhcmFtIHtFbGVtZW50fSBsaW5rXG5cdCAqIEByZXR1cm4gez9zdHJpbmd9XG5cdCAqL1xuXHRtYXliZVBhcnNlTGlua1JvdXRlUGF0aF8obGluaykge1xuXHRcdHZhciBwYXRoID0gbGluay5nZXRBdHRyaWJ1dGUoJ2hyZWYnKTtcblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKHBhdGgpKSB7XG5cdFx0XHRpZiAocGF0aC5pbmRleE9mKCdyZWdleDonKSA9PT0gMCkge1xuXHRcdFx0XHRwYXRoID0gbmV3IFJlZ0V4cChwYXRoLnN1YnN0cmluZyg2KSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBwYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHNldHMgYXBwIGJhc2UgcGF0aCBmcm9tIGBkYXRhLXNlbm5hLWJhc2UtcGF0aGAgZGF0YSBhdHRyaWJ1dGUuXG5cdCAqL1xuXHRtYXliZVNldEJhc2VQYXRoXygpIHtcblx0XHR2YXIgYmFzZVBhdGggPSB0aGlzLmJhc2VFbGVtZW50LmdldEF0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy5iYXNlUGF0aCk7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChiYXNlUGF0aCkpIHtcblx0XHRcdHRoaXMuYXBwLnNldEJhc2VQYXRoKGJhc2VQYXRoKTtcblx0XHRcdGNvbnNvbGUubG9nKCdTZW5uYSBzY2FubmVkIGJhc2UgcGF0aCAnICsgYmFzZVBhdGgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBzZXRzIGFwcCBsaW5rIHNlbGVjdG9yIGZyb20gYGRhdGEtc2VubmEtbGluay1zZWxlY3RvcmAgZGF0YVxuXHQgKiBhdHRyaWJ1dGUuXG5cdCAqL1xuXHRtYXliZVNldExpbmtTZWxlY3Rvcl8oKSB7XG5cdFx0dmFyIGxpbmtTZWxlY3RvciA9IHRoaXMuYmFzZUVsZW1lbnQuZ2V0QXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLmxpbmtTZWxlY3Rvcik7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChsaW5rU2VsZWN0b3IpKSB7XG5cdFx0XHR0aGlzLmFwcC5zZXRMaW5rU2VsZWN0b3IobGlua1NlbGVjdG9yKTtcblx0XHRcdGNvbnNvbGUubG9nKCdTZW5uYSBzY2FubmVkIGxpbmsgc2VsZWN0b3IgJyArIGxpbmtTZWxlY3Rvcik7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHNldHMgYXBwIGxpbmsgbG9hZGluZyBjc3MgY2xhc3MgZnJvbSBgZGF0YS1zZW5uYS1sb2FkaW5nLWNzcy1jbGFzc2Bcblx0ICogZGF0YSBhdHRyaWJ1dGUuXG5cdCAqL1xuXHRtYXliZVNldExvYWRpbmdDc3NDbGFzc18oKSB7XG5cdFx0dmFyIGxvYWRpbmdDc3NDbGFzcyA9IHRoaXMuYmFzZUVsZW1lbnQuZ2V0QXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLmxvYWRpbmdDc3NDbGFzcyk7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChsb2FkaW5nQ3NzQ2xhc3MpKSB7XG5cdFx0XHR0aGlzLmFwcC5zZXRMb2FkaW5nQ3NzQ2xhc3MobG9hZGluZ0Nzc0NsYXNzKTtcblx0XHRcdGNvbnNvbGUubG9nKCdTZW5uYSBzY2FubmVkIGxvYWRpbmcgY3NzIGNsYXNzICcgKyBsb2FkaW5nQ3NzQ2xhc3MpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBzZXRzIGFwcCB1cGRhdGUgc2Nyb2xsIHBvc2l0aW9uIGZyb21cblx0ICogYGRhdGEtc2VubmEtdXBkYXRlLXNjcm9sbC1wb3NpdGlvbmAgZGF0YSBhdHRyaWJ1dGUuXG5cdCAqL1xuXHRtYXliZVNldFVwZGF0ZVNjcm9sbFBvc2l0aW9uXygpIHtcblx0XHR2YXIgdXBkYXRlU2Nyb2xsUG9zaXRpb24gPSB0aGlzLmJhc2VFbGVtZW50LmdldEF0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy51cGRhdGVTY3JvbGxQb3NpdGlvbik7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbCh1cGRhdGVTY3JvbGxQb3NpdGlvbikpIHtcblx0XHRcdGlmICh1cGRhdGVTY3JvbGxQb3NpdGlvbiA9PT0gJ2ZhbHNlJykge1xuXHRcdFx0XHR0aGlzLmFwcC5zZXRVcGRhdGVTY3JvbGxQb3NpdGlvbihmYWxzZSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmFwcC5zZXRVcGRhdGVTY3JvbGxQb3NpdGlvbih0cnVlKTtcblx0XHRcdH1cblx0XHRcdGNvbnNvbGUubG9nKCdTZW5uYSBzY2FubmVkIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gJyArIHVwZGF0ZVNjcm9sbFBvc2l0aW9uKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUXVlcmllcyBlbGVtZW50cyBmcm9tIGRvY3VtZW50IGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGVsZW1lbnRzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yXG5cdCAqIEByZXR1cm4ge2FycmF5LjxFbGVtZW50Pn1cblx0ICovXG5cdHF1ZXJ5U2VsZWN0b3JBbGxBc0FycmF5XyhzZWxlY3Rvcikge1xuXHRcdHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChnbG9iYWxzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIGVsZW1lbnQgaWQgaWYgaGFuZGxlZCBhcyBzcGVjaWFsIHN1cmZhY2UgZWxlbWVudC4gU29tZSBzdXJmYWNlc1xuXHQgKiBhcmUgc2xpZ2h0bHkgZGlmZmVyZW50IGZyb20gb3RoZXJzLCBsaWtlIHdoZW4gdGhyZWF0aW5nIDxjb2RlPmJvZHk8L2NvZGU+XG5cdCAqIGFzIHN1cmZhY2UuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuXHQgKi9cblx0dXBkYXRlRWxlbWVudElkSWZTcGVjaWFsU3VyZmFjZV8oZWxlbWVudCkge1xuXHRcdGlmICghZWxlbWVudC5pZCAmJiBlbGVtZW50ID09PSBnbG9iYWxzLmRvY3VtZW50LmJvZHkpIHtcblx0XHRcdGVsZW1lbnQuaWQgPSAnc2VubmFfc3VyZmFjZV8nICsgZ2V0VWlkKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGJhc2UgZWxlbWVudC5cblx0ICogQHBhcmFtIHtFbGVtZW50fSBiYXNlRWxlbWVudFxuXHQgKi9cblx0c2V0QmFzZUVsZW1lbnQoYmFzZUVsZW1lbnQpIHtcblx0XHR0aGlzLmJhc2VFbGVtZW50ID0gYmFzZUVsZW1lbnQ7XG5cdH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBBcHBEYXRhQXR0cmlidXRlSGFuZGxlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGdsb2JhbHMgZnJvbSAnLi4vZ2xvYmFscy9nbG9iYWxzJztcbmltcG9ydCBBcHBEYXRhQXR0cmlidXRlSGFuZGxlciBmcm9tICcuL0FwcERhdGFBdHRyaWJ1dGVIYW5kbGVyJztcblxuLyoqXG4gKiBEYXRhIGF0dHJpYnV0ZSBoYW5kbGVyLlxuICogQHR5cGUge0FwcERhdGFBdHRyaWJ1dGVIYW5kbGVyfVxuICovXG52YXIgZGF0YUF0dHJpYnV0ZUhhbmRsZXIgPSBuZXcgQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXIoKTtcblxuZ2xvYmFscy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgZnVuY3Rpb24oKSB7XG5cdGRhdGFBdHRyaWJ1dGVIYW5kbGVyLnNldEJhc2VFbGVtZW50KGdsb2JhbHMuZG9jdW1lbnQuYm9keSk7XG5cdGRhdGFBdHRyaWJ1dGVIYW5kbGVyLmhhbmRsZSgpO1xufSk7XG5cbmV4cG9ydCBkZWZhdWx0IGRhdGFBdHRyaWJ1dGVIYW5kbGVyOyIsIi8qKlxuICogQHJldHVybnMgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGN1cnJlbnQgc2VubmEgdmVyc2lvblxuICovXG5cbmNvbnN0IHZlcnNpb24gPSAnPCU9IHZlcnNpb24gJT4nO1xuXG5leHBvcnQgZGVmYXVsdCB2ZXJzaW9uOyJdLCJuYW1lcyI6WyJpc0RlZiIsInZhbCIsInVuZGVmaW5lZCIsImlzRGVmQW5kTm90TnVsbCIsImlzTnVsbCIsImlzRG9jdW1lbnQiLCJub2RlVHlwZSIsImlzRnVuY3Rpb24iLCJpc09iamVjdCIsInR5cGUiLCJpc1N0cmluZyIsIlN0cmluZyIsImlzU2VydmVyU2lkZSIsIm9wdGlvbnMiLCJjaGVja0VudiIsInNlcnZlclNpZGUiLCJwcm9jZXNzIiwiYnJvd3NlciIsImVudiIsIk5PREVfRU5WIiwiYXJyYXkiLCJhcnIxIiwiYXJyMiIsImxlbmd0aCIsImkiLCJhcnIiLCJvdXRwdXQiLCJBcnJheSIsImlzQXJyYXkiLCJmbGF0dGVuIiwicHVzaCIsIm9iaiIsImluZGV4T2YiLCJydiIsInJlbW92ZUF0IiwicHJvdG90eXBlIiwic3BsaWNlIiwiY2FsbCIsInN0YXJ0IiwiZW5kIiwic2xpY2VkIiwiYXN5bmMiLCJ0aHJvd0V4Y2VwdGlvbiIsImV4Y2VwdGlvbiIsIm5leHRUaWNrIiwicnVuIiwiY2FsbGJhY2siLCJjb250ZXh0Iiwid29ya1F1ZXVlU2NoZWR1bGVkXyIsInByb2Nlc3NXb3JrUXVldWUiLCJ3b3JrUXVldWVfIiwiV29ya0l0ZW1fIiwid29ya0l0ZW1zIiwid29ya0l0ZW0iLCJmbiIsInNjb3BlIiwiZSIsImNiIiwiYmluZCIsIndyYXBDYWxsYmFja18iLCJzZXRJbW1lZGlhdGVfIiwic2V0SW1tZWRpYXRlIiwiZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfIiwiQ2hhbm5lbCIsIk1lc3NhZ2VDaGFubmVsIiwid2luZG93IiwicG9zdE1lc3NhZ2UiLCJhZGRFdmVudExpc3RlbmVyIiwiaWZyYW1lIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50Iiwic3R5bGUiLCJkaXNwbGF5Iiwic3JjIiwidGl0bGUiLCJkb2N1bWVudEVsZW1lbnQiLCJhcHBlbmRDaGlsZCIsIndpbiIsImNvbnRlbnRXaW5kb3ciLCJkb2MiLCJvcGVuIiwid3JpdGUiLCJjbG9zZSIsIm1lc3NhZ2UiLCJNYXRoIiwicmFuZG9tIiwib3JpZ2luIiwibG9jYXRpb24iLCJwcm90b2NvbCIsImhvc3QiLCJvbm1lc3NhZ2UiLCJkYXRhIiwicG9ydDEiLCJwb3J0MiIsImNoYW5uZWwiLCJoZWFkIiwidGFpbCIsIm5leHQiLCJzY3JpcHQiLCJvbnJlYWR5c3RhdGVjaGFuZ2UiLCJwYXJlbnROb2RlIiwicmVtb3ZlQ2hpbGQiLCJEaXNwb3NhYmxlIiwiZGlzcG9zZWRfIiwiZGlzcG9zZUludGVybmFsIiwib2JqZWN0IiwidGFyZ2V0Iiwia2V5Iiwic291cmNlIiwiYXJncyIsIm5hbWUiLCJwYXJ0cyIsInNwbGl0IiwicmVkdWNlIiwicGFydCIsIm1hcHBlZE9iaiIsImtleXMiLCJPYmplY3QiLCJvYmoxIiwib2JqMiIsImtleXMxIiwia2V5czIiLCJzdHJpbmciLCJzdHIxIiwic3RyMiIsInRlc3QxIiwidG9Mb3dlckNhc2UiLCJ0ZXN0MiIsInN0ciIsInJlcGxhY2UiLCJ4IiwiZmxvb3IiLCJ0b1N0cmluZyIsImFicyIsIkRhdGUiLCJub3ciLCJoYXNoIiwibGVuIiwiY2hhckNvZGVBdCIsInZhbHVlIiwic3Vic3RyaW5nIiwiTUVUQUxfREFUQSIsImRvbURhdGEiLCJlbGVtZW50IiwiaW5pdGlhbFZhbHVlIiwiRXZlbnRIYW5kbGUiLCJlbWl0dGVyIiwiZXZlbnQiLCJsaXN0ZW5lciIsImVtaXR0ZXJfIiwiZXZlbnRfIiwibGlzdGVuZXJfIiwicmVtb3ZlTGlzdGVuZXIiLCJpc0Rpc3Bvc2VkIiwic2luZ2xlQXJyYXlfIiwiRXZlbnRFbWl0dGVyIiwiZXZlbnRzXyIsImxpc3RlbmVySGFuZGxlcnNfIiwic2hvdWxkVXNlRmFjYWRlXyIsImhvbGRlciIsImhhbmRsZXIiLCJkZWZhdWx0TGlzdGVuZXIiLCJ2YWxpZGF0ZUxpc3RlbmVyXyIsImV2ZW50cyIsInRvRXZlbnRzQXJyYXlfIiwiYWRkU2luZ2xlTGlzdGVuZXJfIiwicnVuTGlzdGVuZXJIYW5kbGVyc18iLCJhZGRIYW5kbGVyXyIsImdldFNob3VsZFVzZUZhY2FkZSIsImZhY2FkZSIsInByZXZlbnRlZERlZmF1bHQiLCJsaXN0ZW5lcnMiLCJnZXRSYXdMaXN0ZW5lcnNfIiwic2xpY2UiLCJhcmd1bWVudHMiLCJydW5MaXN0ZW5lcnNfIiwiYnVpbGRGYWNhZGVfIiwiZGlyZWN0TGlzdGVuZXJzIiwidG9BcnJheSIsImNvbmNhdCIsIm1hcCIsImFtb3VudCIsIm1hbnlfIiwic2VsZiIsImhhbmRsZXJJbnRlcm5hbCIsImFwcGx5IiwibGlzdGVuZXJPYmoiLCJyZW1vdmVNYXRjaGluZ0xpc3RlbmVyT2Jqc18iLCJhZGRMaXN0ZW5lciIsIm1hbnkiLCJsaXN0ZW5lck9ianMiLCJmaW5hbExpc3RlbmVycyIsIm1hdGNoZXNMaXN0ZW5lcl8iLCJvZmYiLCJoYW5kbGVycyIsImRlZmF1bHRMaXN0ZW5lcnMiLCJkZWZhdWx0IiwiaiIsInNob3VsZFVzZUZhY2FkZSIsIlR5cGVFcnJvciIsIkV2ZW50RW1pdHRlclByb3h5Iiwib3JpZ2luRW1pdHRlciIsInRhcmdldEVtaXR0ZXIiLCJibGFja2xpc3QiLCJ3aGl0ZWxpc3QiLCJibGFja2xpc3RfIiwib3JpZ2luRW1pdHRlcl8iLCJwZW5kaW5nRXZlbnRzXyIsInByb3hpZWRFdmVudHNfIiwidGFyZ2V0RW1pdHRlcl8iLCJ3aGl0ZWxpc3RfIiwic3RhcnRQcm94eV8iLCJvbiIsInJlbW92ZUxpc3RlbmVyc18iLCJlbWl0Iiwic2hvdWxkUHJveHlFdmVudF8iLCJ0cnlUb0FkZExpc3RlbmVyXyIsImZvckVhY2giLCJwcm94eUV2ZW50Iiwib25MaXN0ZW5lciIsImFkZExpc3RlbmVyXyIsImVtaXRPblRhcmdldF8iLCJFdmVudEhhbmRsZXIiLCJldmVudEhhbmRsZXNfIiwiRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGUiLCJzZWxlY3RvciIsInNlbGVjdG9yXyIsImRlbGVnYXRpbmciLCJnZXQiLCJzZWxlY3RvcnMiLCJyZW1vdmUiLCJEb21FdmVudEhhbmRsZSIsImNhcHR1cmUiLCJjYXB0dXJlXyIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJlbGVtZW50c0J5VGFnXyIsInN1cHBvcnRDYWNoZV8iLCJjdXN0b21FdmVudHMiLCJMQVNUX0NPTlRBSU5FUiIsIlVTRV9DQVBUVVJFIiwiYWRkQ2xhc3NlcyIsImVsZW1lbnRzIiwiY2xhc3NlcyIsImFkZENsYXNzZXNXaXRoTmF0aXZlXyIsImNsYXNzTmFtZSIsImNsYXNzTGlzdCIsImFkZCIsImFkZENsYXNzZXNXaXRob3V0TmF0aXZlXyIsImVsZW1lbnRDbGFzc05hbWUiLCJjbGFzc2VzVG9BcHBlbmQiLCJhZGRFbGVtZW50TGlzdGVuZXJfIiwiZXZlbnROYW1lIiwiYWRkU2VsZWN0b3JMaXN0ZW5lcl8iLCJkZWxlZ2F0aW5nRGF0YSIsImFkZFRvQXJyXyIsImF0dGFjaERlbGVnYXRlRXZlbnRfIiwiaGFuZGxlRGVsZWdhdGVFdmVudF8iLCJjbG9zZXN0IiwibWF0Y2giLCJhcHBlbmQiLCJwYXJlbnQiLCJjaGlsZCIsImJ1aWxkRnJhZ21lbnQiLCJpc05vZGVMaXN0TGlrZSIsImNoaWxkQXJyIiwiaHRtbFN0cmluZyIsInRlbXBEaXYiLCJpbm5lckhUTUwiLCJmaXJzdENoaWxkIiwiZnJhZ21lbnQiLCJjcmVhdGVEb2N1bWVudEZyYWdtZW50IiwiY29udGFpbnMiLCJlbGVtZW50MSIsImVsZW1lbnQyIiwiZGVsZWdhdGUiLCJzZWxlY3Rvck9yVGFyZ2V0IiwiY3VzdG9tQ29uZmlnIiwib3JpZ2luYWxFdmVudCIsImRlZmF1bHRMaXN0ZW5lcl8iLCJpc0FibGVUb0ludGVyYWN0V2l0aF8iLCJub2RlIiwiZXZlbnRPYmoiLCJidXR0b24iLCJtYXRjaGVzU2VsZWN0b3IiLCJ0YWdOYW1lIiwiZGlzYWJsZWQiLCJpdGVtIiwiZXhpdERvY3VtZW50IiwicmV0IiwiY29udGFpbmVyIiwiY3VycmVudFRhcmdldCIsImRlZkZucyIsInRyaWdnZXJEZWxlZ2F0ZWRMaXN0ZW5lcnNfIiwidHJpZ2dlckRlZmF1bHREZWxlZ2F0ZWRMaXN0ZW5lcnNfIiwiZGVsZWdhdGVUYXJnZXQiLCJwIiwiRWxlbWVudCIsIm0iLCJtYXRjaGVzIiwid2Via2l0TWF0Y2hlc1NlbGVjdG9yIiwibW96TWF0Y2hlc1NlbGVjdG9yIiwibXNNYXRjaGVzU2VsZWN0b3IiLCJvTWF0Y2hlc1NlbGVjdG9yIiwibWF0Y2hGYWxsYmFja18iLCJub2RlcyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJub3JtYWxpemVEZWxlZ2F0ZUV2ZW50XyIsInN0b3BQcm9wYWdhdGlvbiIsInN0b3BQcm9wYWdhdGlvbl8iLCJzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24iLCJzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25fIiwib25jZSIsImRvbUV2ZW50SGFuZGxlIiwicmVnaXN0ZXJDdXN0b21FdmVudCIsInJlbW92ZUNoaWxkcmVuIiwicmVtb3ZlQ2xhc3NlcyIsInJlbW92ZUNsYXNzZXNXaXRoTmF0aXZlXyIsInJlbW92ZUNsYXNzZXNXaXRob3V0TmF0aXZlXyIsInRyaW0iLCJzdG9wcGVkIiwic3RvcHBlZEltbWVkaWF0ZSIsInN1cHBvcnRzRXZlbnQiLCJ0YWciLCJoYXNPd25Qcm9wZXJ0eSIsImRlZmF1bHRQcmV2ZW50ZWQiLCJkZWZhdWx0Rm5zIiwiY3VyckVsZW1lbnQiLCJsaW1pdCIsInRyaWdnZXJFbGVtZW50TGlzdGVuZXJzXyIsInRyaWdnZXJTZWxlY3Rvckxpc3RlbmVyc18iLCJsYXN0Q29udGFpbmVyIiwidHJpZ2dlckxpc3RlbmVyc18iLCJEb21FdmVudEVtaXR0ZXJQcm94eSIsImlzRGVsZWdhdGVFdmVudF8iLCJpbmRleCIsInN1YnN0ciIsImJhYmVsSGVscGVycy5nZXQiLCJpc1N1cHBvcnRlZERvbUV2ZW50XyIsImZlYXR1cmVzIiwiYW5pbWF0aW9uRXZlbnROYW1lXyIsImNoZWNrQW5pbWF0aW9uRXZlbnROYW1lXyIsInByZWZpeGVzIiwidHlwZVRpdGxlQ2FzZSIsInJlcGxhY2VJbnRlcnZhbCIsInRvVXBwZXJDYXNlIiwic3VmZml4ZXMiLCJhbmltYXRpb25FbGVtZW50XyIsImF0dHJPcmRlckNoYW5nZV8iLCJvcmlnaW5hbENvbnRlbnQiLCJnbG9iYWxFdmFsIiwidGV4dCIsImFwcGVuZEZuIiwiZGVmYXVsdEZuIiwicnVuRmlsZSIsInNjcmlwdHMiLCJydW5TY3JpcHRzSW5PcmRlciIsInJ1blNjcmlwdCIsImdsb2JhbEV2YWxTdHlsZXMiLCJocmVmIiwibGluayIsInJlbCIsInJ1blN0eWxlIiwic3R5bGVzIiwibG9hZENvdW50IiwicmVnaXN0ZXJFdmVudHMiLCJtb3VzZUV2ZW50TWFwIiwicmVsYXRlZCIsInJlbGF0ZWRUYXJnZXQiLCJjdXN0b21UeXBlIiwiYW5pbWF0aW9uRXZlbnRNYXAiLCJldmVudFR5cGUiLCJjaGVja0FuaW1hdGlvbkV2ZW50TmFtZSIsImdsb2JhbHMiLCJjb21wYXRpYmlsaXR5TW9kZURhdGFfIiwidW5pcXVlSWRDb3VudGVyXyIsIlVJRF9QUk9QRVJUWSIsImFic3RyYWN0TWV0aG9kIiwiRXJyb3IiLCJkaXNhYmxlQ29tcGF0aWJpbGl0eU1vZGUiLCJlbmFibGVDb21wYXRpYmlsaXR5TW9kZSIsImdldENvbXBhdGliaWxpdHlNb2RlRGF0YSIsIl9fTUVUQUxfQ09NUEFUSUJJTElUWV9fIiwiZ2V0Rmlyc3RUcnV0aHlfIiwiYSIsImIiLCJnZXRGdW5jdGlvbk5hbWUiLCJnZXRTdGF0aWNQcm9wZXJ0eSIsImN0b3IiLCJwcm9wZXJ0eU5hbWUiLCJtZXJnZUZuIiwibWVyZ2VkTmFtZSIsIm1lcmdlZCIsIl9fcHJvdG9fXyIsImlzUHJvdG90eXBlT2YiLCJGdW5jdGlvbiIsImdldFVpZCIsIm5vSW5oZXJpdGFuY2UiLCJpZCIsImlkZW50aXR5RnVuY3Rpb24iLCJyZXR1cm5WYWx1ZSIsImlzQm9vbGVhbiIsImlzRG9jdW1lbnRGcmFnbWVudCIsImlzRWxlbWVudCIsImlzTnVtYmVyIiwiaXNXaW5kb3ciLCJpc1Byb21pc2UiLCJ0aGVuIiwibnVsbEZ1bmN0aW9uIiwicGFyc2VGcm9tQW5jaG9yIiwib3B0X3VyaSIsInRlc3QiLCJob3N0bmFtZSIsInBhc3N3b3JkIiwicGF0aG5hbWUiLCJwb3J0Iiwic2VhcmNoIiwidXNlcm5hbWUiLCJwYXJzZSIsIlVSTCIsInVybCIsImNyZWF0ZSIsIk11bHRpTWFwIiwidmFsdWVzIiwic2l6ZSIsIm5hbWVzIiwiSlNPTiIsInN0cmluZ2lmeSIsInNldCIsIlRyZWVOb2RlIiwidmFsdWVfIiwicGFyZW50XyIsImNoaWxkcmVuXyIsInNldFBhcmVudCIsImN1cnJlbnQiLCJnZXRQYXJlbnQiLCJhbmNlc3RvcnMiLCJnZXRDaGlsZHJlbiIsIkVNUFRZX0FSUkFZIiwiZGVwdGgiLCJyb290IiwiZ2V0Q2hpbGRDb3VudCIsIm9wdF9wcmVvcmRlckZuIiwib3B0X3Bvc3RvcmRlckZuIiwidHJhdmVyc2UiLCJhc3NlcnRDaGlsZEhhc05vUGFyZW50IiwicGFyc2VGbl8iLCJVcmkiLCJtYXliZUFkZFByb3RvY29sQW5kSG9zdG5hbWVfIiwibXVsdGltYXAiLCJnZXRBbGwiLCJhZGRQYXJhbWV0ZXJWYWx1ZSIsImVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfIiwicXVlcnkiLCJwYXJhbSIsInVybERlY29kZSIsImdldEhvc3RuYW1lIiwiZ2V0UG9ydCIsIkhPU1ROQU1FX1BMQUNFSE9MREVSIiwiZ2V0SG9zdCIsImdldFByb3RvY29sIiwicXVlcnlzdHJpbmciLCJnZXRQYXJhbWV0ZXJOYW1lcyIsImdldFBhcmFtZXRlclZhbHVlcyIsImVuY29kZVVSSUNvbXBvbmVudCIsInNldFBhcmFtZXRlclZhbHVlIiwiUkFORE9NX1BBUkFNIiwiZ2V0UmFuZG9tU3RyaW5nIiwiREVGQVVMVF9QUk9UT0NPTCIsImNoYXJBdCIsInJlbW92ZVBhcmFtZXRlciIsImdldFBhdGhuYW1lIiwiZ2V0U2VhcmNoIiwiZ2V0SGFzaCIsInBhcnNlRm4iLCJiYXNlUGF0aCIsInBhdGhzIiwicGF0aCIsImpvaW4iLCJkZWNvZGVVUklDb21wb25lbnQiLCJpc1NlY3VyZSIsInV0aWxzIiwiYXR0cmlidXRlcyIsImF0dHJpYnV0ZSIsInNldEF0dHJpYnV0ZSIsImdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoIiwib2Zmc2V0TGVmdCIsIm9mZnNldFRvcCIsIm9mZnNldFBhcmVudCIsInVyaSIsImN1cnJlbnRCcm93c2VyUGF0aCIsImdldFVybFBhdGhXaXRob3V0SGFzaCIsImdldFVybFBhdGgiLCJoaXN0b3J5IiwicHVzaFN0YXRlIiwiZXJyIiwiZXJyb3IiLCJyZW1vdmVBdHRyaWJ1dGUiLCJyZWZlcnJlciIsImRlZmluZVByb3BlcnR5IiwiVGhlbmFibGUiLCJJTVBMRU1FTlRFRF9CWV9QUk9QIiwiYWRkSW1wbGVtZW50YXRpb24iLCIkZ29vZ19UaGVuYWJsZSIsImlzSW1wbGVtZW50ZWRCeSIsInBhcnRpYWwiLCJuZXdBcmdzIiwiQ2FuY2VsbGFibGVQcm9taXNlIiwicmVzb2x2ZXIiLCJvcHRfY29udGV4dCIsInN0YXRlXyIsIlN0YXRlXyIsIlBFTkRJTkciLCJyZXN1bHRfIiwiY2FsbGJhY2tFbnRyaWVzXyIsImV4ZWN1dGluZ18iLCJVTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZIiwidW5oYW5kbGVkUmVqZWN0aW9uSWRfIiwiaGFkVW5oYW5kbGVkUmVqZWN0aW9uXyIsInJlc29sdmVfIiwiRlVMRklMTEVEIiwicmVhc29uIiwiUkVKRUNURUQiLCJDYWxsYmFja0VudHJ5XyIsInJlc29sdmUiLCJvcHRfdmFsdWUiLCJyZWplY3QiLCJvcHRfcmVhc29uIiwicmFjZSIsInByb21pc2VzIiwicHJvbWlzZSIsImFsbCIsInRvRnVsZmlsbCIsIm9uRnVsZmlsbCIsIm9uUmVqZWN0IiwiZmlyc3RGdWxmaWxsZWQiLCJ0b1JlamVjdCIsInJlYXNvbnMiLCJvcHRfb25GdWxmaWxsZWQiLCJvcHRfb25SZWplY3RlZCIsImFkZENoaWxkUHJvbWlzZV8iLCJ0aGVuQWx3YXlzIiwib25SZXNvbHZlZCIsImhhbmRsZVJlamVjdGlvbl8iLCJhZGRDYWxsYmFja0VudHJ5XyIsInRoZW5DYXRjaCIsIm9uUmVqZWN0ZWQiLCJjYXRjaCIsImNhbmNlbCIsIm9wdF9tZXNzYWdlIiwiQ2FuY2VsbGF0aW9uRXJyb3IiLCJJU19DQU5DRUxMQVRJT05fRVJST1IiLCJjYW5jZWxJbnRlcm5hbF8iLCJjYW5jZWxDaGlsZF8iLCJjaGlsZFByb21pc2UiLCJjaGlsZENvdW50IiwiY2hpbGRJbmRleCIsImVudHJ5IiwiY2FsbGJhY2tFbnRyeSIsImV4ZWN1dGVDYWxsYmFja18iLCJzY2hlZHVsZUNhbGxiYWNrc18iLCJvbkZ1bGZpbGxlZCIsInJlc3VsdCIsInVuYmxvY2tBbmRGdWxmaWxsXyIsIkJMT0NLRUQiLCJ1bmJsb2NrQW5kUmVqZWN0XyIsInN0YXRlIiwidHJ5VGhlbl8iLCJhZGRVbmhhbmRsZWRSZWplY3Rpb25fIiwidGhlbmFibGUiLCJjYWxsZWQiLCJleGVjdXRlQ2FsbGJhY2tzXyIsImVudHJpZXMiLCJyZW1vdmVVbmhhbmRsZWRSZWplY3Rpb25fIiwic2V0VGltZW91dCIsInNldFVuaGFuZGxlZFJlamVjdGlvbkhhbmRsZXIiLCJkZWJvdW5jZSIsImRlbGF5IiwiZGVib3VuY2VkIiwiY2FuY2VsRGVib3VuY2UiLCJSRUdFWCIsImNvbnZlcnRNYXRjaGVzVG9PYmoiLCJjb252ZXJ0VG9rZW5zVG9SZWdleCIsInRva2VucyIsInJlZ2V4IiwiY29yZSIsImVzY2FwZSIsImVuY2xvc2VOb25DYXB0dXJpbmdHcm91cCIsInBhdHRlcm4iLCJyZXBlYXQiLCJwcmVmaXgiLCJvcHRpb25hbCIsIlJlZ0V4cCIsIm1ha2VUcmFpbGluZ1NsYXNoT3B0aW9uYWwiLCJyb3V0ZU9yVG9rZW5zIiwicm91dGUiLCJ1bm5hbWVkQ291bnQiLCJjdXJyUGF0aCIsImV4ZWMiLCJwYXJhbVBhdHRlcm4iLCJ1bm5hbWVkUGF0dGVybiIsIm1vZGlmaWVyIiwidG9SZWdleCIsImV4dHJhY3REYXRhIiwicGFyYW1JbmRleCIsIlJvdXRlIiwicGFyc2VkRGF0YV8iLCJidWlsZFBhcnNlZERhdGFfIiwiQ2FjaGVhYmxlIiwiY2FjaGUiLCJjYWNoZWFibGUiLCJjb250ZW50IiwiY2xlYXJDYWNoZSIsIlNjcmVlbiIsIm1ha2VJZF8iLCJtZXRhcyIsImxvZyIsInN1cmZhY2VzIiwic0lkIiwiYWN0aXZlQ2hpbGQiLCJydW5TY3JpcHRzSW5FbGVtZW50IiwidHJhbnNpdGlvbnMiLCJzdXJmYWNlIiwiZGVmZXJyZWQiLCJzaG93IiwiU3VyZmFjZSIsImRlZmF1bHRDaGlsZCIsInRyYW5zaXRpb25GbiIsImdldENoaWxkIiwiREVGQVVMVCIsIm1heWJlV3JhcENvbnRlbnRBc0RlZmF1bHRfIiwic2NyZWVuSWQiLCJvcHRfY29udGVudCIsImNyZWF0ZUNoaWxkIiwidHJhbnNpdGlvbiIsImdldEVsZW1lbnQiLCJnZXRFbGVtZW50QnlJZCIsImFkZENvbnRlbnQiLCJmcm9tIiwidG8iLCJkZWZhdWx0VHJhbnNpdGlvbiIsIk5hdmlnYXRpb25TdHJhdGVneSIsIkFwcCIsImFjdGl2ZVNjcmVlbiIsImFjdGl2ZVBhdGgiLCJhbGxvd1ByZXZlbnROYXZpZ2F0ZSIsImJyb3dzZXJQYXRoQmVmb3JlTmF2aWdhdGUiLCJjYXB0dXJlU2Nyb2xsUG9zaXRpb25Gcm9tU2Nyb2xsRXZlbnQiLCJkZWZhdWx0VGl0bGUiLCJmb3JtU2VsZWN0b3IiLCJpZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGgiLCJsaW5rU2VsZWN0b3IiLCJsb2FkaW5nQ3NzQ2xhc3MiLCJuYXRpdmVTY3JvbGxSZXN0b3JhdGlvblN1cHBvcnRlZCIsIm5hdmlnYXRpb25TdHJhdGVneSIsIklNTUVESUFURSIsImlzTmF2aWdhdGlvblBlbmRpbmciLCJwZW5kaW5nTmF2aWdhdGUiLCJwb3BzdGF0ZVNjcm9sbExlZnQiLCJwb3BzdGF0ZVNjcm9sbFRvcCIsInJlZGlyZWN0UGF0aCIsInJvdXRlcyIsInNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZSIsInNjcmVlbnMiLCJza2lwTG9hZFBvcHN0YXRlIiwidXBkYXRlU2Nyb2xsUG9zaXRpb24iLCJhcHBFdmVudEhhbmRsZXJzXyIsIm9uU2Nyb2xsXyIsIm9uTG9hZF8iLCJvblBvcHN0YXRlXyIsIm9uU3RhcnROYXZpZ2F0ZV8iLCJvbkJlZm9yZU5hdmlnYXRlXyIsIm9uQmVmb3JlTmF2aWdhdGVEZWZhdWx0XyIsIm9uQmVmb3JlVW5sb2FkRGVmYXVsdF8iLCJzZXRMaW5rU2VsZWN0b3IiLCJzZXRGb3JtU2VsZWN0b3IiLCJtYXliZU92ZXJsb2FkQmVmb3JlVW5sb2FkXyIsImdldElkIiwiaXNXZWJVcmkiLCJpc0xpbmtTYW1lT3JpZ2luXyIsImlzU2FtZUJhc2VQYXRoXyIsImlzQ3VycmVudEJyb3dzZXJQYXRoIiwiZmluZFJvdXRlIiwicmVtb3ZlU2NyZWVuIiwic2NyZWVuIiwiZ2V0SGFuZGxlciIsImNsZWFyU2NyZWVuc0NhY2hlIiwiZm9ybUV2ZW50SGFuZGxlcl8iLCJsaW5rRXZlbnRIYW5kbGVyXyIsInJlbW92ZUFsbExpc3RlbmVycyIsIm5hdmlnYXRlIiwiZ2V0Q3VycmVudEJyb3dzZXJQYXRoIiwib3B0X3JlcGxhY2VIaXN0b3J5Iiwic3RvcFBlbmRpbmdOYXZpZ2F0ZV8iLCJuZXh0U2NyZWVuIiwiY3JlYXRlU2NyZWVuSW5zdGFuY2UiLCJtYXliZVByZXZlbnREZWFjdGl2YXRlXyIsIm1heWJlUHJldmVudEFjdGl2YXRlXyIsImxvYWQiLCJTQ0hFRFVMRV9MQVNUIiwiZGVhY3RpdmF0ZSIsInByZXBhcmVOYXZpZ2F0ZUhpc3RvcnlfIiwicHJlcGFyZU5hdmlnYXRlU3VyZmFjZXNfIiwiZXh0cmFjdFBhcmFtcyIsImV2YWx1YXRlU3R5bGVzIiwiZmxpcCIsImV2YWx1YXRlU2NyaXB0cyIsIm1heWJlVXBkYXRlU2Nyb2xsUG9zaXRpb25TdGF0ZV8iLCJzeW5jU2Nyb2xsUG9zaXRpb25TeW5jVGhlbkFzeW5jXyIsImZpbmFsaXplTmF2aWdhdGVfIiwiaGFuZGxlTmF2aWdhdGVFcnJvcl8iLCJzY2hlZHVsZWROYXZpZ2F0aW9uIiwic2hpZnQiLCJtYXliZU5hdmlnYXRlXyIsImdldFJvdXRlUGF0aCIsImFjdGl2YXRlIiwiaXNDYWNoZWFibGUiLCJjYXB0dXJlZEZvcm1FbGVtZW50IiwiY2FwdHVyZWRGb3JtQnV0dG9uRWxlbWVudCIsIm1hdGNoZXNQYXRoIiwiZ2V0SWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoIiwiZ2V0VXJsUGF0aFdpdGhvdXRIYXNoQW5kU2VhcmNoIiwic3RhY2siLCJob3N0VXJpIiwibG9jYXRpb25Ib3N0VXJpIiwid2lubmVyIiwic3dpdGNoU2Nyb2xsUG9zaXRpb25SYWNlIiwic2Nyb2xsVG8iLCJzY3JvbGxMZWZ0Iiwic2Nyb2xsVG9wIiwibmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25fIiwic2Nyb2xsUmVzdG9yYXRpb24iLCJtaXhpbiIsImNhbk5hdmlnYXRlIiwiaXNOYXZpZ2F0aW9uU2NoZWR1bGVkIiwibWF5YmVTY2hlZHVsZU5hdmlnYXRpb25fIiwicHJldmVudERlZmF1bHQiLCJuYXZpZ2F0ZUZhaWxlZCIsImlzU2NoZWR1bGVkTmF2aWdhdGlvbiIsIm9uYmVmb3JldW5sb2FkIiwiX29uYmVmb3JldW5sb2FkIiwiX292ZXJsb2FkZWQiLCJiZWZvcmVBY3RpdmF0ZSIsInByZXZlbnQiLCJiZWZvcmVEZWFjdGl2YXRlIiwiYW5jaG9yRWxlbWVudCIsImdldE5vZGVPZmZzZXQiLCJzYXZlSGlzdG9yeUN1cnJlbnRQYWdlU2Nyb2xsUG9zaXRpb25fIiwib3B0X2V2ZW50IiwiaXNIdG1sNUhpc3RvcnlTdXBwb3J0ZWQiLCJmb3JtIiwicmVwbGFjZUhpc3RvcnkiLCJmdW5jIiwiYWx0S2V5IiwiY3RybEtleSIsIm1ldGFLZXkiLCJzaGlmdEtleSIsIm1ldGhvZCIsImJ1dHRvblNlbGVjdG9yIiwiYWN0aXZlRWxlbWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJhY3Rpb24iLCJtYXliZVJlcG9zaXRpb25TY3JvbGxUb0hhc2hlZEFuY2hvciIsInJlbG9hZFBhZ2UiLCJzZW5uYSIsImxvY2tIaXN0b3J5U2Nyb2xsUG9zaXRpb25fIiwic2V0UmVmZXJyZXIiLCJzZXRIb3N0bmFtZSIsInNldFBvcnQiLCJwYWdlWU9mZnNldCIsInBhZ2VYT2Zmc2V0IiwibWF5YmVEaXNhYmxlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb24iLCJlbmROYXZpZ2F0ZVBheWxvYWQiLCJkb05hdmlnYXRlXyIsIm1heWJlUmVzdG9yZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uIiwiZ2V0VGl0bGUiLCJnZXREZWZhdWx0VGl0bGUiLCJiZWZvcmVVcGRhdGVIaXN0b3J5UGF0aCIsImhpc3RvcnlTdGF0ZSIsIm1heWJlUmVzdG9yZVJlZGlyZWN0UGF0aEhhc2hfIiwidXBkYXRlSGlzdG9yeV8iLCJiZWZvcmVVcGRhdGVIaXN0b3J5U3RhdGUiLCJwYXJhbXMiLCJzdXJmYWNlQ29udGVudCIsImdldFN1cmZhY2VDb250ZW50IiwicmVsb2FkIiwic3VyZmFjZUlkIiwiZGlzcG9zZSIsInJlcGxhY2VTdGF0ZSIsInJlbW92ZVBhdGhUcmFpbGluZ1NsYXNoIiwib25Eb2NTdWJtaXREZWxlZ2F0ZV8iLCJvbkRvY0NsaWNrRGVsZWdhdGVfIiwic3luYyIsInRpdGxlTm9kZSIsIkFqYXgiLCJhbGxIZWFkZXJzIiwiaGVhZGVycyIsInBhaXJzIiwiYm9keSIsIm9wdF9oZWFkZXJzIiwib3B0X3BhcmFtcyIsIm9wdF90aW1lb3V0Iiwib3B0X3N5bmMiLCJvcHRfd2l0aENyZWRlbnRpYWxzIiwicmVxdWVzdCIsIlhNTEh0dHBSZXF1ZXN0IiwicHJldmlvdXNSZWFkeVN0YXRlIiwiUHJvbWlzZSIsIm9ubG9hZCIsImFib3J0ZWQiLCJvbmVycm9yIiwicmVhZHlTdGF0ZSIsInRlcm1pbmF0ZWRQcmVtYXR1cmVseSIsImFib3J0IiwidGltZW91dCIsImFkZFBhcmFtZXRlcnNGcm9tTXVsdGlNYXAiLCJ3aXRoQ3JlZGVudGlhbHMiLCJzZXRSZXF1ZXN0SGVhZGVyIiwic2VuZCIsImVycm9ycyIsIklOVkFMSURfU1RBVFVTIiwiUkVRVUVTVF9FUlJPUiIsIlJFUVVFU1RfVElNRU9VVCIsIlJFUVVFU1RfUFJFTUFUVVJFX1RFUk1JTkFUSU9OIiwiVUEiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJwbGF0Zm9ybSIsImlzTWFjIiwibWF0Y2hQbGF0Zm9ybSIsImlzV2luIiwiaXNPcGVyYSIsIm1hdGNoVXNlckFnZW50IiwiaXNJZSIsImlzRWRnZSIsImlzSWVPckVkZ2UiLCJpc0Nocm9tZSIsImlzU2FmYXJpIiwiaXNGaXJlZm94IiwidGVzdFVzZXJBZ2VudCIsImdldE5hdGl2ZVVzZXJBZ2VudCIsImdldE5hdGl2ZVBsYXRmb3JtIiwiUmVxdWVzdFNjcmVlbiIsImh0dHBIZWFkZXJzIiwiaHR0cE1ldGhvZCIsIkdFVCIsInN0YXR1cyIsImlzVmFsaWRSZXNwb25zZVN0YXR1c0NvZGUiLCJpbnZhbGlkU3RhdHVzIiwic3RhdHVzQ29kZSIsImdldFJlcXVlc3RQYXRoIiwic2V0UHJvdG9jb2wiLCJtYWtlVW5pcXVlIiwiZ2V0UmVxdWVzdCIsInJlcXVlc3RQYXRoIiwicmVzcG9uc2VVcmwiLCJtYXliZUV4dHJhY3RSZXNwb25zZVVybEZyb21SZXF1ZXN0IiwicmVtb3ZlVW5pcXVlIiwiZm9ybUVsZW1lbnQiLCJzdWJtaXR0ZWRCdXR0b25FbGVtZW50IiwiZm9ybURhdGEiLCJGb3JtRGF0YSIsIm1heWJlQXBwZW5kU3VibWl0QnV0dG9uVmFsdWVfIiwiZ2V0Q2FjaGUiLCJoZWFkZXIiLCJhZGRTYWZhcmlYSFJQb2x5ZmlsbCIsImdldEZvcm1EYXRhIiwiUE9TVCIsImZvcm1hdExvYWRQYXRoIiwicmVtb3ZlU2FmYXJpWEhSUG9seWZpbGwiLCJzZXRSZXF1ZXN0IiwieGhyIiwiYXNzZXJ0VmFsaWRSZXNwb25zZVN0YXR1c0NvZGUiLCJhZGRDYWNoZSIsInJlc3BvbnNlVGV4dCIsInJlcXVlc3RFcnJvciIsInJlcXVlc3RQcmVtYXR1cmVUZXJtaW5hdGlvbiIsInJlc3BvbnNlVVJMIiwiZ2V0UmVzcG9uc2VIZWFkZXIiLCJYX1JFUVVFU1RfVVJMX0hFQURFUiIsImlucHV0cyIsImlucHV0IiwiZmlsZXMiLCJIdG1sU2NyZWVuIiwibWV0YVRhZ3NTZWxlY3RvciIsInRpdGxlU2VsZWN0b3IiLCJyZWxlYXNlVmlydHVhbERvY3VtZW50IiwicGVuZGluZ1N0eWxlcyIsInZpcnR1YWxEb2N1bWVudCIsImNvcHlOb2RlQXR0cmlidXRlc0Zyb21Db250ZW50XyIsIm5ld1N0eWxlIiwiaXNUZW1wb3JhcnlTdHlsZSIsInN0eWxlc1RlbXBvcmFyeSIsInN0eWxlSW5Eb2MiLCJpbnNlcnRCZWZvcmUiLCJuZXh0U2libGluZyIsImJvZHlTdXJmYWNlIiwicGxhY2Vob2xkZXIiLCJ0ZW1wTm9kZSIsImNyZWF0ZVJhbmdlIiwiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiwiY2xlYXJOb2RlQXR0cmlidXRlcyIsImNvcHlOb2RlQXR0cmlidXRlcyIsImRpc3Bvc2VQZW5kaW5nU3R5bGVzIiwicmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQiLCJldmFsdWF0ZVRyYWNrZWRTY3JpcHRzIiwiZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyIsInNjcmlwdHNUZW1wb3JhcnkiLCJzY3JpcHRzUGVybWFuZW50IiwiZXZhbHVhdGVUcmFja2VkU3R5bGVzIiwicnVuU3R5bGVzSW5FbGVtZW50Iiwic3R5bGVzUGVybWFuZW50IiwiYXBwZW5kU3R5bGVJbnRvRG9jdW1lbnRfIiwicmVzb3VyY2VzSW5WaXJ0dWFsIiwidmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfIiwiZmF2aWNvbiIsInJlc291cmNlc0luRG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yQWxsXyIsInJ1bkZhdmljb25JbkVsZW1lbnRfIiwiZXZhbHVhdG9yRm4iLCJzZWxlY3RvclRlbXBvcmFyeSIsInNlbGVjdG9yUGVybWFuZW50Iiwib3B0X2FwcGVuZFJlc291cmNlRm4iLCJ0cmFja2VkIiwidGVtcG9yYXJpZXNJbkRvYyIsInBlcm1hbmVudHNJbkRvYyIsInJlc291cmNlIiwicmVzb3VyY2VLZXkiLCJnZXRSZXNvdXJjZUtleV8iLCJwZXJtYW5lbnRSZXNvdXJjZXNJbkRvYyIsImZyYWciLCJldmFsdWF0ZUZhdmljb25fIiwidXBkYXRlTWV0YVRhZ3NfIiwiY3VycmVudE1ldGFOb2RlcyIsIm1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudCIsIm1ldGEiLCJhbGxvY2F0ZVZpcnR1YWxEb2N1bWVudEZvckNvbnRlbnQiLCJyZXNvbHZlVGl0bGVGcm9tVmlydHVhbERvY3VtZW50IiwicmVzb2x2ZU1ldGFUYWdzRnJvbVZpcnR1YWxEb2N1bWVudCIsImFzc2VydFNhbWVCb2R5SWRJblZpcnR1YWxEb2N1bWVudCIsIm1ha2VUZW1wb3JhcnlTdHlsZXNIcmVmc1VuaXF1ZV8iLCJyZXBsYWNlU3R5bGVBbmRNYWtlVW5pcXVlXyIsInJlcGxhY2VDaGlsZCIsInNldEVsZW1lbnRXaXRoUmFuZG9tSHJlZiIsInNldFRpdGxlIiwidGV4dENvbnRlbnQiLCJzZXRNZXRhcyIsImlnbm9yZUZhdmljb24iLCJBcHBEYXRhQXR0cmlidXRlSGFuZGxlciIsImFwcCIsImJhc2VFbGVtZW50IiwiaGFzQXR0cmlidXRlIiwiZGF0YUF0dHJpYnV0ZXMiLCJtYXliZUFkZFJvdXRlc18iLCJtYXliZUFkZFN1cmZhY2VzXyIsIm1heWJlU2V0QmFzZVBhdGhfIiwibWF5YmVTZXRMaW5rU2VsZWN0b3JfIiwibWF5YmVTZXRMb2FkaW5nQ3NzQ2xhc3NfIiwibWF5YmVTZXRVcGRhdGVTY3JvbGxQb3NpdGlvbl8iLCJtYXliZURpc3BhdGNoXyIsInJvdXRlc1NlbGVjdG9yIiwicXVlcnlTZWxlY3RvckFsbEFzQXJyYXlfIiwibWF5YmVQYXJzZUxpbmtSb3V0ZV8iLCJoYXNSb3V0ZXMiLCJhZGRSb3V0ZXMiLCJzdXJmYWNlc1NlbGVjdG9yIiwic3VyZmFjZUVsZW1lbnQiLCJ1cGRhdGVFbGVtZW50SWRJZlNwZWNpYWxTdXJmYWNlXyIsImFkZFN1cmZhY2VzIiwiZGlzcGF0Y2giLCJtYXliZVBhcnNlTGlua1JvdXRlUGF0aF8iLCJtYXliZVBhcnNlTGlua1JvdXRlSGFuZGxlcl8iLCJnZXRQYXRoIiwiZ2V0QXR0cmlidXRlIiwiZ2V0T2JqZWN0QnlOYW1lIiwic2V0QmFzZVBhdGgiLCJzZXRMb2FkaW5nQ3NzQ2xhc3MiLCJzZXRVcGRhdGVTY3JvbGxQb3NpdGlvbiIsImRhdGFBdHRyaWJ1dGVIYW5kbGVyIiwic2V0QmFzZUVsZW1lbnQiLCJoYW5kbGUiLCJ2ZXJzaW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQkE7Ozs7O0FBS0E7Ozs7Ozs7Ozs7OztBQVlBOzs7OztBQU9BOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7Ozs7Ozs7QUFTQTs7QUFVQSxBQVdBOzs7Ozs7O0FBT0E7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"} \ No newline at end of file diff --git a/package.json b/package.json index 0807486..77df38c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "senna", - "version": "2.7.7", + "version": "2.7.8", "description": "A blazing-fast Single Page Application engine", "license": "BSD-3-Clause", "repository": "liferay/senna.js", From 8dccfda27ae4427b5382fade005d2c41d50049fe Mon Sep 17 00:00:00 2001 From: Diego Nascimento <diego.nascimento@liferay.com> Date: Fri, 26 Jul 2019 14:25:24 -0300 Subject: [PATCH 2/2] chore(senna): Update lockfile --- package-lock.json | 8424 +++++++++++++++++++++++++-------------------- 1 file changed, 4717 insertions(+), 3707 deletions(-) diff --git a/package-lock.json b/package-lock.json index 31b895a..3517c31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "senna", - "version": "2.7.6", + "version": "2.7.8", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,11 +10,11 @@ "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", "dev": true, "requires": { - "acorn": "5.1.1", - "css": "2.2.1", - "normalize-path": "2.1.1", - "source-map": "0.5.6", - "through2": "2.0.3" + "acorn": "^5.0.3", + "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.1.1", - "through2": "2.0.3" + "normalize-path": "^2.0.1", + "through2": "^2.0.3" } }, "abbrev": { @@ -39,7 +39,7 @@ "integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=", "dev": true, "requires": { - "mime-types": "2.1.16", + "mime-types": "~2.1.6", "negotiator": "0.5.3" } }, @@ -55,7 +55,7 @@ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "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.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" } }, "amdefine": { @@ -124,8 +124,8 @@ "dev": true, "optional": true, "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" } }, "archy": { @@ -140,7 +140,7 @@ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", "dev": true, "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "arr-diff": { @@ -149,7 +149,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "arr-flatten": { @@ -188,7 +188,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { @@ -240,12 +240,12 @@ "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", "dev": true, "requires": { - "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" + "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" } }, "babel-cli": { @@ -254,21 +254,21 @@ "integrity": "sha1-IHzXBbumFImy6kG1MSNBz2rKIoM=", "dev": true, "requires": { - "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-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-code-frame": { @@ -277,9 +277,9 @@ "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.0" } }, "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.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-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-generator": { @@ -315,14 +315,14 @@ "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", "dev": true, "requires": { - "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-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-helper-call-delegate": { @@ -331,10 +331,10 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-define-map": { @@ -343,10 +343,10 @@ "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", "dev": true, "requires": { - "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": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1", + "lodash": "^4.2.0" } }, "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.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "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": { @@ -368,8 +368,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-hoist-variables": { @@ -378,8 +378,8 @@ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-optimise-call-expression": { @@ -388,8 +388,8 @@ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-regex": { @@ -398,9 +398,9 @@ "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1", + "lodash": "^4.2.0" } }, "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.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "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-helpers": { @@ -423,8 +423,8 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-template": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-messages": { @@ -433,7 +433,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-check-es2015-constants": { @@ -442,7 +442,7 @@ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-external-helpers": { @@ -451,7 +451,7 @@ "integrity": "sha1-IoX0iwK9Xe3oUXXK+MYuhq3M76E=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-search-and-replace": { @@ -466,7 +466,7 @@ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -475,7 +475,7 @@ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -484,11 +484,11 @@ "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", "dev": true, "requires": { - "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-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1", + "lodash": "^4.2.0" } }, "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.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "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-plugin-transform-es2015-computed-properties": { @@ -514,8 +514,8 @@ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-template": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-destructuring": { @@ -524,7 +524,7 @@ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -533,8 +533,8 @@ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-for-of": { @@ -543,7 +543,7 @@ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.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.25.0", - "babel-types": "6.25.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-literals": { @@ -563,7 +563,7 @@ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.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.25.0", - "babel-template": "6.25.0" + "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": { @@ -583,10 +583,10 @@ "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", "dev": true, "requires": { - "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-strict-mode": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" } }, "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.25.0", - "babel-template": "6.25.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "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.25.0", - "babel-template": "6.25.0" + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "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.25.0" + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.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.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "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-plugin-transform-es2015-shorthand-properties": { @@ -641,8 +641,8 @@ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-spread": { @@ -651,7 +651,7 @@ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.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.25.0", - "babel-types": "6.25.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-template-literals": { @@ -671,7 +671,7 @@ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -680,7 +680,7 @@ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "6.25.0" + "babel-runtime": "^6.22.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.25.0", - "regexpu-core": "2.0.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.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.25.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-polyfill": { @@ -731,9 +731,9 @@ "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" + "babel-runtime": "^6.22.0", + "core-js": "^2.4.0", + "regenerator-runtime": "^0.10.0" } }, "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.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-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-preset-es2015-rollup": { @@ -774,9 +774,9 @@ "integrity": "sha1-hUtj7N4u6YysQOiC9nv88YWx8ko=", "dev": true, "requires": { - "babel-plugin-external-helpers": "6.22.0", - "babel-preset-es2015": "6.24.1", - "require-relative": "0.8.7" + "babel-plugin-external-helpers": "^6.18.0", + "babel-preset-es2015": "^6.3.13", + "require-relative": "^0.8.7" } }, "babel-preset-metal": { @@ -785,7 +785,7 @@ "integrity": "sha1-WoRpOLkqmOtkDHzZpBEm/X7M25E=", "dev": true, "requires": { - "babel-preset-es2015": "6.24.1" + "babel-preset-es2015": "^6.1.18" } }, "babel-register": { @@ -794,13 +794,13 @@ "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", "dev": true, "requires": { - "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-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-runtime": { @@ -809,8 +809,8 @@ "integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.10.0" } }, "babel-template": { @@ -819,11 +819,11 @@ "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "lodash": "4.17.4" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.25.0", + "babel-types": "^6.25.0", + "babylon": "^6.17.2", + "lodash": "^4.2.0" } }, "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.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-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-types": { @@ -849,10 +849,10 @@ "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.22.0", + "esutils": "^2.0.2", + "lodash": "^4.2.0", + "to-fast-properties": "^1.0.1" } }, "babylon": { @@ -898,7 +898,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "beeper": { @@ -920,7 +920,7 @@ "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", "dev": true, "requires": { - "readable-stream": "1.0.34" + "readable-stream": "~1.0.26" }, "dependencies": { "isarray": { @@ -935,10 +935,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -962,15 +962,15 @@ "dev": true, "requires": { "bytes": "2.1.0", - "content-type": "1.0.2", - "debug": "2.2.0", - "depd": "1.0.1", - "http-errors": "1.3.1", + "content-type": "~1.0.1", + "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.7", - "type-is": "1.6.15" + "raw-body": "~2.1.2", + "type-is": "~1.6.6" }, "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.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "expand-range": "^1.8.1", + "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.30000708", - "electron-to-chromium": "1.3.16" + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" } }, "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.1.1", - "map-obj": "1.0.1" + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" }, "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.4", - "lazy-cache": "1.0.4" + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" } }, "chai": { @@ -1137,11 +1137,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "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" + "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" } }, "chokidar": { @@ -1151,15 +1151,15 @@ "dev": true, "optional": true, "requires": { - "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" + "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" } }, "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.3", - "right-align": "0.1.3", + "center-align": "^0.1.1", + "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { @@ -1240,7 +1240,7 @@ "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=", "dev": true, "requires": { - "mime-db": "1.29.0" + "mime-db": ">= 1.29.0 < 2" } }, "compression": { @@ -1249,12 +1249,12 @@ "integrity": "sha1-sDuNhub4rSloPLqN+R3cb/x3s5U=", "dev": true, "requires": { - "accepts": "1.2.13", + "accepts": "~1.2.12", "bytes": "2.1.0", - "compressible": "2.0.11", - "debug": "2.2.0", - "on-headers": "1.0.1", - "vary": "1.0.1" + "compressible": "~2.0.5", + "debug": "~2.2.0", + "on-headers": "~1.0.0", + "vary": "~1.0.1" }, "dependencies": { "debug": { @@ -1286,9 +1286,9 @@ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", "dev": true, "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "concat-with-sourcemaps": { @@ -1297,7 +1297,7 @@ "integrity": "sha1-9Vs74q60dgGxCi1SWcz7cP0vHdY=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "^0.5.1" } }, "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.2", + "compression": "~1.5.2", + "connect-timeout": "~1.6.2", + "content-type": "~1.0.1", "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.3", - "express-session": "1.11.3", + "csurf": "~1.8.3", + "debug": "~2.2.0", + "depd": "~1.0.1", + "errorhandler": "~1.4.2", + "express-session": "~1.11.3", "finalhandler": "0.4.0", "fresh": "0.3.0", - "http-errors": "1.3.1", - "method-override": "2.3.9", - "morgan": "1.6.1", + "http-errors": "~1.3.1", + "method-override": "~2.3.5", + "morgan": "~1.6.1", "multiparty": "3.3.2", - "on-headers": "1.0.1", - "parseurl": "1.3.1", + "on-headers": "~1.0.0", + "parseurl": "~1.3.0", "pause": "0.1.0", "qs": "4.0.0", - "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", + "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", "utils-merge": "1.0.0", - "vhost": "3.0.2" + "vhost": "~3.0.1" }, "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.1" + "on-headers": "~1.0.0" }, "dependencies": { "debug": { @@ -1460,10 +1460,10 @@ "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", "dev": true, "requires": { - "inherits": "2.0.3", - "source-map": "0.1.43", - "source-map-resolve": "0.3.1", - "urix": "0.1.0" + "inherits": "^2.0.1", + "source-map": "^0.1.38", + "source-map-resolve": "^0.3.0", + "urix": "^0.1.0" }, "dependencies": { "source-map": { @@ -1472,7 +1472,7 @@ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -1485,8 +1485,8 @@ "requires": { "cookie": "0.1.3", "cookie-signature": "1.0.6", - "csrf": "3.0.6", - "http-errors": "1.3.1" + "csrf": "~3.0.0", + "http-errors": "~1.3.1" } }, "currently-unhandled": { @@ -1495,7 +1495,7 @@ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "1.0.2" + "array-find-index": "^1.0.1" } }, "d": { @@ -1504,7 +1504,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.24" + "es5-ext": "^0.10.9" } }, "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.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.1" + "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" } }, "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.1" + "repeating": "^2.0.0" } }, "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.3", - "entities": "1.1.1" + "domelementtype": "~1.1.1", + "entities": "~1.1.1" }, "dependencies": { "domelementtype": { @@ -1689,7 +1689,7 @@ "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", "dev": true, "requires": { - "domelementtype": "1.3.0" + "domelementtype": "1" } }, "domutils": { @@ -1698,8 +1698,8 @@ "integrity": "sha1-GVjMC0yUJuntNn+xyOhUiRsPo/8=", "dev": true, "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.0" + "dom-serializer": "0", + "domelementtype": "1" } }, "duplexer": { @@ -1714,7 +1714,7 @@ "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", "dev": true, "requires": { - "readable-stream": "1.1.14" + "readable-stream": "~1.1.9" }, "dependencies": { "isarray": { @@ -1729,10 +1729,10 @@ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -1750,7 +1750,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "ee-first": { @@ -1771,7 +1771,7 @@ "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", "dev": true, "requires": { - "once": "1.3.3" + "once": "~1.3.0" }, "dependencies": { "once": { @@ -1780,7 +1780,7 @@ "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } } } @@ -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.3", - "escape-html": "1.0.3" + "accepts": "~1.3.0", + "escape-html": "~1.0.3" }, "dependencies": { "accepts": { @@ -1816,7 +1816,7 @@ "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", "dev": true, "requires": { - "mime-types": "2.1.16", + "mime-types": "~2.1.11", "negotiator": "0.6.1" } }, @@ -1834,8 +1834,8 @@ "integrity": "sha1-pVh3yZJLwMjZvTwsvhdJWsFwmxQ=", "dev": true, "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "es6-iterator": "2", + "es6-symbol": "~3.1" } }, "es6-iterator": { @@ -1844,9 +1844,9 @@ "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "es6-symbol": "^3.1" } }, "es6-map": { @@ -1855,12 +1855,12 @@ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "dev": true, "requires": { - "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" + "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" } }, "es6-plato": { @@ -1869,11 +1869,11 @@ "integrity": "sha1-CSfhXORiC9+OEfBaTVwd3GveW3s=", "dev": true, "requires": { - "eslint": "3.19.0", - "fs-extra": "2.1.2", - "glob": "7.1.2", - "lodash": "4.17.4", - "posix-getopt": "1.2.0", + "eslint": "^3.9.1", + "fs-extra": "^2.0.0", + "glob": "^7.1.1", + "lodash": "^4.16.6", + "posix-getopt": "^1.2.0", "typhonjs-escomplex": "0.0.12" } }, @@ -1883,11 +1883,11 @@ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", + "d": "1", + "es5-ext": "~0.10.14", + "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.0.0", - "es5-ext": "0.10.24" + "d": "1", + "es5-ext": "~0.10.14" } }, "es6-weak-map": { @@ -1906,10 +1906,10 @@ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "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.2", - "source-map": "0.5.6" + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "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.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", - "estraverse": "4.2.0" + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint": { @@ -2000,41 +2000,41 @@ "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "strip-bom": { @@ -2049,7 +2049,7 @@ "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.0" } } } @@ -2060,8 +2060,8 @@ "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", "dev": true, "requires": { - "acorn": "5.1.1", - "acorn-jsx": "3.0.1" + "acorn": "^5.0.1", + "acorn-jsx": "^3.0.0" } }, "esprima": { @@ -2076,7 +2076,7 @@ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { @@ -2085,8 +2085,8 @@ "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", "dev": true, "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" + "estraverse": "^4.1.0", + "object-assign": "^4.0.1" } }, "estraverse": { @@ -2119,8 +2119,8 @@ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24" + "d": "1", + "es5-ext": "~0.10.14" } }, "event-stream": { @@ -2129,13 +2129,13 @@ "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { - "duplexer": "0.1.1", - "from": "0.1.7", - "map-stream": "0.1.0", + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" } }, "exit-hook": { @@ -2150,7 +2150,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "expand-range": { @@ -2159,7 +2159,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.3" + "fill-range": "^2.1.0" } }, "expand-tilde": { @@ -2168,7 +2168,7 @@ "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.1" } }, "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.1", - "parseurl": "1.3.1", - "uid-safe": "2.0.0", + "debug": "~2.2.0", + "depd": "~1.0.1", + "on-headers": "~1.0.0", + "parseurl": "~1.3.0", + "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.3", - "time-stamp": "1.1.0" + "chalk": "^1.1.1", + "time-stamp": "^1.0.0" } }, "fast-levenshtein": { @@ -2251,7 +2251,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": "0.6.5" + "websocket-driver": ">=0.5.1" } }, "figures": { @@ -2260,8 +2260,8 @@ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, "file-entry-cache": { @@ -2270,8 +2270,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "filename-regex": { @@ -2286,11 +2286,11 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "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.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "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.11", - "resolve-dir": "0.1.1" + "detect-file": "^0.1.0", + "is-glob": "^2.0.1", + "micromatch": "^2.3.7", + "resolve-dir": "^0.1.0" } }, "fined": { @@ -2362,11 +2362,11 @@ "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", "dev": true, "requires": { - "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" + "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" }, "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.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, "for-in": { @@ -2416,7 +2416,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "formatio": { @@ -2425,7 +2425,7 @@ "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", "dev": true, "requires": { - "samsam": "1.1.2" + "samsam": "~1.1" } }, "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.11", - "jsonfile": "2.4.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" } }, "fs-readdir-recursive": { @@ -2484,182 +2484,208 @@ "dev": true, "optional": true, "requires": { - "nan": "2.6.2", - "node-pre-gyp": "0.6.36" + "nan": "^2.3.0", + "node-pre-gyp": "^0.6.36" }, "dependencies": { "abbrev": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", "dev": true, "optional": true }, "ajv": { "version": "4.11.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "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": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "aproba": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "asn1": { "version": "0.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", "dev": true, "optional": true }, "assert-plus": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", "dev": true, "optional": true }, "asynckit": { "version": "0.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true, "optional": true }, "aws-sign2": { "version": "0.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", "dev": true, "optional": true }, "aws4": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", "dev": true, "optional": true }, "balanced-match": { "version": "0.4.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", "dev": true }, "bcrypt-pbkdf": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "dev": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "block-stream": { "version": "0.0.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "boom": { "version": "2.10.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "brace-expansion": { "version": "1.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", "dev": true, "requires": { - "balanced-match": "0.4.2", + "balanced-match": "^0.4.1", "concat-map": "0.0.1" } }, "buffer-shims": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", "dev": true }, "caseless": { "version": "0.12.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true, "optional": true }, "co": { "version": "4.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "combined-stream": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, "core-util-is": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "cryptiles": { "version": "2.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", "dev": true, "optional": true, "requires": { - "boom": "2.10.1" + "boom": "2.x.x" } }, "dashdash": { "version": "1.14.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, "optional": true } @@ -2667,7 +2693,8 @@ }, "debug": { "version": "2.6.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", "dev": true, "optional": true, "requires": { @@ -2676,113 +2703,127 @@ }, "deep-extend": { "version": "0.4.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", "dev": true, "optional": true }, "delayed-stream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, "delegates": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "ecc-jsbn": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "extend": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "dev": true, "optional": true }, "extsprintf": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", "dev": true }, "forever-agent": { "version": "0.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true, "optional": true }, "form-data": { "version": "2.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", "dev": true, "optional": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" } }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "fstream": { "version": "1.0.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "fstream-ignore": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", "dev": true, "optional": true, "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" } }, "gauge": { "version": "2.7.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, "requires": { - "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" + "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" } }, "getpass": { "version": "0.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, "optional": true } @@ -2790,162 +2831,184 @@ }, "glob": { "version": "7.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "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" + "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" } }, "graceful-fs": { "version": "4.1.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "har-schema": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", "dev": true, "optional": true }, "har-validator": { "version": "4.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", "dev": true, "optional": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "^4.9.1", + "har-schema": "^1.0.5" } }, "has-unicode": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "hawk": { "version": "3.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", "dev": true, "optional": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "hoek": { "version": "2.16.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", "dev": true }, "http-signature": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", "dev": true, "optional": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "ini": { "version": "1.3.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-typedarray": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true, "optional": true }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isstream": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true, "optional": true }, "jodid25519": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "jsbn": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true, "optional": true }, "json-schema": { "version": "0.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true, "optional": true }, "json-stable-stringify": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "dev": true, "optional": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stringify-safe": { "version": "5.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true, "optional": true }, "jsonify": { "version": "0.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true, "optional": true }, "jsprim": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", "dev": true, "optional": true, "requires": { @@ -2957,7 +3020,8 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, "optional": true } @@ -2965,33 +3029,38 @@ }, "mime-db": { "version": "1.27.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", "dev": true }, "mime-types": { "version": "2.1.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", "dev": true, "requires": { - "mime-db": "1.27.0" + "mime-db": "~1.27.0" } }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.7" + "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -2999,139 +3068,157 @@ }, "ms": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true, "optional": true }, "node-pre-gyp": { "version": "0.6.36", - "bundled": true, + "resolved": false, + "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=", "dev": true, "optional": true, "requires": { - "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" + "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" } }, "nopt": { "version": "4.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npmlog": { "version": "4.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==", "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "oauth-sign": { "version": "0.8.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "performance-now": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", "dev": true, "optional": true }, "process-nextick-args": { "version": "1.0.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "punycode": { "version": "1.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true, "optional": true }, "qs": { "version": "6.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", "dev": true, "optional": true }, "rc": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", "dev": true, "optional": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true } @@ -3139,108 +3226,118 @@ }, "readable-stream": { "version": "2.2.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", "dev": true, "requires": { - "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" + "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" } }, "request": { "version": "2.81.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", "dev": true, "optional": true, "requires": { - "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" + "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" } }, "rimraf": { "version": "2.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { "version": "5.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", "dev": true }, "semver": { "version": "5.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "sntp": { "version": "1.0.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", "dev": true, "optional": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "sshpk": { "version": "1.13.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", "dev": true, "optional": true, "requires": { - "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" + "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" }, "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, "optional": true } @@ -3248,112 +3345,126 @@ }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", "dev": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "stringstream": { "version": "0.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", "dev": true, "optional": true }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-pack": { "version": "3.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=", "dev": true, "optional": true, "requires": { - "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" + "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" } }, "tough-cookie": { "version": "2.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", "dev": true, "optional": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { "version": "0.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "optional": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { "version": "0.14.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true, "optional": true }, "uid-number": { "version": "0.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", "dev": true, "optional": true }, "util-deprecate": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "uuid": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", "dev": true, "optional": true }, "verror": { "version": "1.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", "dev": true, "optional": true, "requires": { @@ -3362,16 +3473,18 @@ }, "wide-align": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true } } @@ -3382,7 +3495,7 @@ "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", "dev": true, "requires": { - "globule": "0.1.0" + "globule": "~0.1.0" } }, "generate-function": { @@ -3397,7 +3510,7 @@ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", "dev": true, "requires": { - "is-property": "1.0.2" + "is-property": "^1.0.0" } }, "get-stdin": { @@ -3412,12 +3525,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "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" + "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" } }, "glob-base": { @@ -3426,8 +3539,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" } }, "glob-parent": { @@ -3436,7 +3549,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "glob-stream": { @@ -3445,12 +3558,12 @@ "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "glob": { @@ -3459,10 +3572,10 @@ "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" } }, "isarray": { @@ -3477,7 +3590,7 @@ "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.0.0" } }, "readable-stream": { @@ -3486,10 +3599,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -3504,8 +3617,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } } } @@ -3516,7 +3629,7 @@ "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", "dev": true, "requires": { - "gaze": "0.5.2" + "gaze": "^0.5.1" } }, "glob2base": { @@ -3525,7 +3638,7 @@ "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", "dev": true, "requires": { - "find-index": "0.1.1" + "find-index": "^0.1.1" } }, "global-modules": { @@ -3534,8 +3647,8 @@ "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", "dev": true, "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" } }, "global-prefix": { @@ -3544,10 +3657,10 @@ "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", "dev": true, "requires": { - "homedir-polyfill": "1.0.1", - "ini": "1.3.4", - "is-windows": "0.2.0", - "which": "1.2.14" + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" } }, "globals": { @@ -3562,12 +3675,12 @@ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "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" + "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" } }, "globule": { @@ -3576,9 +3689,9 @@ "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", "dev": true, "requires": { - "glob": "3.1.21", - "lodash": "1.0.2", - "minimatch": "0.2.14" + "glob": "~3.1.21", + "lodash": "~1.0.1", + "minimatch": "~0.2.11" }, "dependencies": { "glob": { @@ -3587,9 +3700,9 @@ "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", "dev": true, "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.2", - "minimatch": "0.2.14" + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" } }, "graceful-fs": { @@ -3616,8 +3729,8 @@ "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", "dev": true, "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" + "lru-cache": "2", + "sigmund": "~1.0.0" } } } @@ -3628,7 +3741,7 @@ "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", "dev": true, "requires": { - "sparkles": "1.0.0" + "sparkles": "^1.0.0" } }, "graceful-fs": { @@ -3649,19 +3762,19 @@ "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "minimist": { @@ -3678,11 +3791,11 @@ "integrity": "sha1-dSMAUc0NFxND14O36bXREg7u+bA=", "dev": true, "requires": { - "autoprefixer": "6.7.7", - "gulp-util": "3.0.8", - "postcss": "5.2.17", - "through2": "2.0.3", - "vinyl-sourcemaps-apply": "0.2.1" + "autoprefixer": "^6.0.0", + "gulp-util": "^3.0.0", + "postcss": "^5.0.4", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" } }, "gulp-connect": { @@ -3691,11 +3804,11 @@ "integrity": "sha1-8v3zBq6RFGg2jCKF8teC8T7dr04=", "dev": true, "requires": { - "connect": "2.30.2", - "connect-livereload": "0.5.4", - "event-stream": "3.3.4", - "gulp-util": "3.0.8", - "tiny-lr": "0.2.1" + "connect": "^2.30.0", + "connect-livereload": "^0.5.4", + "event-stream": "^3.3.2", + "gulp-util": "^3.0.6", + "tiny-lr": "^0.2.1" } }, "gulp-header": { @@ -3704,10 +3817,10 @@ "integrity": "sha1-yfEP7gYy2B6Tl4nG7PRaFRvzCYs=", "dev": true, "requires": { - "concat-with-sourcemaps": "1.0.4", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "through2": "2.0.3" + "concat-with-sourcemaps": "*", + "gulp-util": "*", + "object-assign": "*", + "through2": "^2.0.0" } }, "gulp-jsdoc3": { @@ -3716,11 +3829,11 @@ "integrity": "sha1-Yek1IS6qlrXC5yvD1n0e3d8VKTo=", "dev": true, "requires": { - "bluebird": "3.5.0", - "debug": "2.6.8", - "gulp-util": "3.0.8", - "ink-docstrap": "1.3.0", - "jsdoc": "3.5.3", + "bluebird": "^3.1.1", + "debug": "^2.2.0", + "gulp-util": "^3.0.7", + "ink-docstrap": "^1.1.4", + "jsdoc": "^3.4.1", "map-stream": "0.0.6", "tmp": "0.0.28" }, @@ -3739,784 +3852,876 @@ "integrity": "sha512-SfD7B/3gdc+go261GWql9i/08yq24ZKnTVSzdRpBvdn5n9yZXcWBghxW0zzAQxhgHGBNh1dKakT6i6NUtzcu9Q==", "dev": true, "requires": { - "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", + "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", "open": "0.0.5", - "run-sequence": "1.2.2", + "run-sequence": "^1.1.0", "typhonjs-escomplex": "0.0.12" }, "dependencies": { "abbrev": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", "dev": true }, "accepts": { "version": "1.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", "dev": true, "requires": { - "mime-types": "2.1.15", + "mime-types": "~2.1.11", "negotiator": "0.6.1" } }, "acorn": { "version": "5.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=", "dev": true }, "acorn-jsx": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "dependencies": { "acorn": { "version": "3.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true } } }, "adm-zip": { "version": "0.4.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=", "dev": true }, "after": { "version": "0.8.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, "agent-base": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", "dev": true, "requires": { - "extend": "3.0.1", - "semver": "5.0.3" + "extend": "~3.0.0", + "semver": "~5.0.1" }, "dependencies": { "semver": { "version": "5.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", "dev": true } } }, "ajv": { "version": "4.11.8", - "bundled": true, + "resolved": false, + "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": { "version": "1.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", "dev": true }, "align-text": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" } }, "amdefine": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, "ansi-escapes": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "anymatch": { "version": "1.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", "dev": true, "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11" + "arrify": "^1.0.0", + "micromatch": "^2.1.5" } }, "aproba": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", "dev": true }, "archiver": { "version": "0.14.4", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-W53bn17hzu8hy487Ag5iQOy0MVw=", + "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" }, "dependencies": { "async": { "version": "0.9.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", "dev": true }, "glob": { "version": "4.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-gPuwjKVA8jiszl0R0em8QedRc9M=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" } }, "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "lodash": { "version": "3.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-S/UKMkP5rrC6xBpV09WZBnWkYvs=", "dev": true }, "minimatch": { "version": "2.0.10", - "bundled": true, + "resolved": false, + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.0.0" } }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "are-we-there-yet": { "version": "1.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "dev": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.11" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "argparse": { "version": "1.0.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", "dev": true, "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "arr-diff": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.0.3" + "arr-flatten": "^1.0.1" } }, "arr-flatten": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", "dev": true }, "array-differ": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", "dev": true }, "array-find-index": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, "array-slice": { "version": "0.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", "dev": true }, "array-union": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", "dev": true }, "array-unique": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, "arraybuffer.slice": { "version": "0.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", "dev": true }, "arrify": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "asn1": { "version": "0.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", "dev": true }, "assert-plus": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", "dev": true }, "assertion-error": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", "dev": true }, "async": { "version": "0.2.10", - "bundled": true, + "resolved": false, + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", "dev": true }, "async-each": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, "async-foreach": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", "dev": true }, "asynckit": { "version": "0.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, "aws-sign2": { "version": "0.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", "dev": true }, "aws4": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", "dev": true }, "babel-code-frame": { "version": "6.22.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.1" + "chalk": "^1.1.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.0" } }, "babel-core": { "version": "6.25.0", - "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.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" + "resolved": false, + "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-deps": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-QGxFzUWhXRbDNPRTZjnGwJh/cbI=", "dev": true, "requires": { - "babel-core": "6.25.0", - "merge": "1.2.0" + "babel-core": "^6.3.0", + "merge": "^1.2.0" } }, "babel-generator": { "version": "6.25.0", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "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" }, "dependencies": { "jsesc": { "version": "1.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true } } }, "babel-globals": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-rHOzwtGwq6YzCS7SrwSNN1KLvkI=", "dev": true, "requires": { - "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-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-helper-call-delegate": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-define-map": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", "dev": true, "requires": { - "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": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1", + "lodash": "^4.2.0" } }, "babel-helper-function-name": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "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": "^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": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-hoist-variables": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-optimise-call-expression": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-regex": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1", + "lodash": "^4.2.0" } }, "babel-helper-replace-supers": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "dev": true, "requires": { - "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-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-helpers": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-messages": { "version": "6.23.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-check-es2015-constants": { "version": "6.22.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-external-helpers-2": { "version": "6.3.13", - "bundled": true, + "resolved": false, + "integrity": "sha1-9oCYbKWu01xYRMQvfwemzWGjqFI=", "dev": true, "requires": { - "babel-runtime": "5.8.38" + "babel-runtime": "^5.0.0" }, "dependencies": { "babel-runtime": { "version": "5.8.38", - "bundled": true, + "resolved": false, + "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=", "dev": true, "requires": { - "core-js": "1.2.7" + "core-js": "^1.0.0" } }, "core-js": { "version": "1.2.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", "dev": true } } }, "babel-plugin-globals": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-gk0ASV6SHnC5pHP1aH4q2jz6awM=", "dev": true, "requires": { - "babel-core": "6.25.0" + "babel-core": "^6.1.2" } }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { "version": "6.22.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoping": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", "dev": true, "requires": { - "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-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1", + "lodash": "^4.2.0" } }, "babel-plugin-transform-es2015-classes": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "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.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "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-plugin-transform-es2015-computed-properties": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-destructuring": { "version": "6.23.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-for-of": { "version": "6.23.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-function-name": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "dev": true, "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-literals": { "version": "6.22.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-modules-amd": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "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": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-commonjs": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", "dev": true, "requires": { - "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-strict-mode": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-systemjs": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "dev": true, "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-umd": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-object-super": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "dev": true, "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.23.0" + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-parameters": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "dev": true, "requires": { - "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-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-plugin-transform-es2015-shorthand-properties": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-spread": { "version": "6.22.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-sticky-regex": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "dev": true, "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-template-literals": { "version": "6.22.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { "version": "6.23.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-unicode-regex": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "dev": true, "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.23.0", - "regexpu-core": "2.0.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" } }, "babel-plugin-transform-node-env-inline": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-lcPzKLvQ58wvO3ecRtMwUh1Zu58=", "dev": true }, "babel-plugin-transform-regenerator": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", "dev": true, "requires": { "regenerator-transform": "0.9.11" @@ -4524,157 +4729,173 @@ }, "babel-plugin-transform-strict-mode": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-preset-es2015": { "version": "6.24.1", - "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.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" + "resolved": false, + "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-preset-metal": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-55TKuzcQJ9YyNqDwTQLHKPkRcCU=", "dev": true, "requires": { - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-preset-es2015": "6.24.1", - "resolve": "1.3.3" + "babel-plugin-transform-es2015-classes": "^6.2.2", + "babel-preset-es2015": "^6.1.18", + "resolve": "^1.1.7" } }, "babel-preset-metal-resolve-source": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-cz4euPmxSlHjGlZZ+fK9zMUNVyo=", "dev": true, "requires": { - "resolve": "1.3.3" + "resolve": "^1.1.7" } }, "babel-register": { "version": "6.24.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", "dev": true, "requires": { - "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-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-runtime": { "version": "6.23.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", "dev": true, "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.10.0" } }, "babel-template": { "version": "6.25.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.3", - "lodash": "4.17.4" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.25.0", + "babel-types": "^6.25.0", + "babylon": "^6.17.2", + "lodash": "^4.2.0" } }, "babel-traverse": { "version": "6.25.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", "dev": true, "requires": { - "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-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-types": { "version": "6.25.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.22.0", + "esutils": "^2.0.2", + "lodash": "^4.2.0", + "to-fast-properties": "^1.0.1" } }, "babylon": { "version": "6.17.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-mq0x3HCAGGmQyZXviOVe5TRsw37Ijy3D43jCqt/9WVf+onx2dUgW3PosnqCbScAFhRO9DGs8nxoMzU0iiosMqQ==", "dev": true }, "backo2": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", "dev": true }, "balanced-match": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "base64-arraybuffer": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", "dev": true }, "base64id": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", "dev": true }, "beeper": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", "dev": true }, "better-assert": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", "dev": true, "requires": { "callsite": "1.0.0" @@ -4682,83 +4903,94 @@ }, "binary-extensions": { "version": "1.8.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", "dev": true }, "binaryextensions": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-HmN0iLNbWL2l9HdL+WpSEqjJB1U=", "dev": true }, "bl": { "version": "0.9.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", "dev": true, "requires": { - "readable-stream": "1.0.34" + "readable-stream": "~1.0.26" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "blob": { "version": "0.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", "dev": true }, "block-stream": { "version": "0.0.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "bluebird": { "version": "3.4.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", "dev": true }, "body-parser": { "version": "1.17.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", "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": { "version": "2.6.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", "dev": true, "requires": { "ms": "2.0.0" @@ -4768,116 +5000,133 @@ }, "boom": { "version": "2.10.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "bower": { "version": "1.8.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Vdvr7wrZFVOC2enT5JfBNyNFtEo=", "dev": true }, "brace-expansion": { "version": "1.1.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { "version": "1.8.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "buffer-crc32": { "version": "0.2.13", - "bundled": true, + "resolved": false, + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, "bufferstreams": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-AWE3MGCsWYjv+ZBYcxEU9uGV1R4=", "dev": true, "requires": { - "readable-stream": "2.2.11" + "readable-stream": "^2.0.2" } }, "builtin-modules": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, "bytes": { "version": "2.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", "dev": true }, "caller-path": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "0.2.0" + "callsites": "^0.2.0" } }, "callsite": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", "dev": true }, "callsites": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, "camelcase": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true }, "camelcase-keys": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" } }, "caseless": { "version": "0.12.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "catharsis": { "version": "0.8.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-aTR59DqsVJ2Aa9c+kkzQ2USVGgY=", "dev": true, "requires": { - "underscore-contrib": "0.3.0" + "underscore-contrib": "~0.3.0" } }, "center-align": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" } }, "chai": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ii9qNHSNqAEJD9cyh7Kqc5pOkJo=", "dev": true, "requires": { "assertion-error": "1.0.0", @@ -4886,219 +5135,248 @@ }, "chalk": { "version": "1.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "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" + "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" } }, "chokidar": { "version": "1.7.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "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" + "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" } }, "circular-json": { "version": "0.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=", "dev": true }, "cli": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", "dev": true, "requires": { "exit": "0.1.2", - "glob": "7.1.2" + "glob": "^7.1.1" } }, "cli-cursor": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", "dev": true, "requires": { - "restore-cursor": "1.0.1" + "restore-cursor": "^1.0.1" } }, "cli-width": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", "dev": true }, "cliui": { "version": "3.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, "clone": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", "dev": true }, "clone-buffer": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", "dev": true }, "clone-stats": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", "dev": true }, "cloneable-readable": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", "dev": true, "requires": { - "inherits": "2.0.3", - "process-nextick-args": "1.0.7", - "through2": "2.0.3" + "inherits": "^2.0.1", + "process-nextick-args": "^1.0.6", + "through2": "^2.0.1" } }, "co": { "version": "4.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "colors": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, "combine-lists": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", "dev": true, "requires": { - "lodash": "4.17.4" + "lodash": "^4.5.0" } }, "combined-stream": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { "version": "2.9.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "requires": { - "graceful-readlink": "1.0.1" + "graceful-readlink": ">= 1.0.0" } }, "component-bind": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", "dev": true }, "component-emitter": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", "dev": true }, "component-inherit": { "version": "0.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", "dev": true }, "compress-commons": { "version": "0.2.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-Qi2SdDDAGr0GzUVbbfwEy0z4ADw=", "dev": true, "requires": { - "buffer-crc32": "0.2.13", - "crc32-stream": "0.3.4", - "node-int64": "0.3.3", - "readable-stream": "1.0.34" + "buffer-crc32": "~0.2.1", + "crc32-stream": "~0.3.1", + "node-int64": "~0.3.0", + "readable-stream": "~1.0.26" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "concat-stream": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", "dev": true, "requires": { - "inherits": "2.0.3", - "readable-stream": "2.2.11", - "typedarray": "0.0.6" + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "concat-with-sourcemaps": { "version": "1.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-9Vs74q60dgGxCi1SWcz7cP0vHdY=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "^0.5.1" } }, "connect": { "version": "3.6.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-aU6NIGgb/kkCgsiriGvpjwn0L+c=", "dev": true, "requires": { "debug": "2.6.7", "finalhandler": "1.0.3", - "parseurl": "1.3.1", + "parseurl": "~1.3.1", "utils-merge": "1.0.0" }, "dependencies": { "debug": { "version": "2.6.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", "dev": true, "requires": { "ms": "2.0.0" @@ -5108,161 +5386,185 @@ }, "console-browserify": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { - "date-now": "0.1.4" + "date-now": "^0.1.4" } }, "console-control-strings": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, "content-type": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", "dev": true }, "convert-source-map": { "version": "1.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", "dev": true }, "cookie": { "version": "0.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", "dev": true }, "core-js": { "version": "2.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", "dev": true }, "core-util-is": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "crc32-stream": { "version": "0.3.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-c7wltF+sHbZjIjGnv86JJ+nwZVI=", "dev": true, "requires": { - "buffer-crc32": "0.2.13", - "readable-stream": "1.0.34" + "buffer-crc32": "~0.2.1", + "readable-stream": "~1.0.24" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "cross-spawn": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", "dev": true, "requires": { - "lru-cache": "4.1.1", - "which": "1.2.14" + "lru-cache": "^4.0.1", + "which": "^1.2.9" }, "dependencies": { "lru-cache": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } } } }, "cryptiles": { "version": "2.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", "dev": true, "requires": { - "boom": "2.10.1" + "boom": "2.x.x" } }, "ctype": { "version": "0.5.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", "dev": true }, "currently-unhandled": { "version": "0.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "1.0.2" + "array-find-index": "^1.0.1" } }, "custom-event": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", "dev": true }, "d": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.23" + "es5-ext": "^0.10.9" } }, "dashdash": { "version": "1.14.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } }, "date-now": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, "dateformat": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", "dev": true }, "deap": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-sUi/gkMKJ2mbdIOgPra2dYW/yIg=", "dev": true }, "debug": { "version": "2.6.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", "dev": true, "requires": { "ms": "2.0.0" @@ -5270,12 +5572,14 @@ }, "decamelize": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "deep-eql": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", "dev": true, "requires": { "type-detect": "0.1.1" @@ -5283,206 +5587,234 @@ }, "deep-is": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "del": { "version": "2.2.2", - "bundled": true, + "resolved": false, + "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.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.1" + "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" } }, "delayed-stream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, "delegates": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, "depd": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=", "dev": true }, "detect-indent": { "version": "4.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "di": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", "dev": true }, "diff": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", "dev": true }, "disparity": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-V92stHMkrl9Y0swNqIbbTOnutxg=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "diff": "1.4.0" + "ansi-styles": "^2.0.1", + "diff": "^1.3.2" } }, "doctrine": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", "dev": true, "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "esutils": "^2.0.2", + "isarray": "^1.0.0" } }, "dom-serialize": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", "dev": true, "requires": { - "custom-event": "1.0.1", - "ent": "2.2.0", - "extend": "3.0.1", - "void-elements": "2.0.1" + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" } }, "dom-serializer": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", "dev": true, "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.1" + "domelementtype": "~1.1.1", + "entities": "~1.1.1" }, "dependencies": { "domelementtype": { "version": "1.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", "dev": true }, "entities": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", "dev": true } } }, "domelementtype": { "version": "1.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", "dev": true }, "domhandler": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", "dev": true, "requires": { - "domelementtype": "1.3.0" + "domelementtype": "1" } }, "domutils": { "version": "1.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", "dev": true, "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.0" + "dom-serializer": "0", + "domelementtype": "1" } }, "duplexer": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, "duplexer2": { "version": "0.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", "dev": true, "requires": { - "readable-stream": "1.1.14" + "readable-stream": "~1.1.9" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.1.14", - "bundled": true, + "resolved": false, + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "duplexify": { "version": "3.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=", "dev": true, "requires": { "end-of-stream": "1.0.0", - "inherits": "2.0.3", - "readable-stream": "2.2.11", - "stream-shift": "1.0.0" + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" }, "dependencies": { "end-of-stream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4=", "dev": true, "requires": { - "once": "1.3.3" + "once": "~1.3.0" } }, "once": { "version": "1.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } } } }, "ee-first": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, "encodeurl": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", "dev": true }, "engine.io": { "version": "1.8.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", "dev": true, "requires": { "accepts": "1.3.3", @@ -5495,7 +5827,8 @@ "dependencies": { "debug": { "version": "2.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", "dev": true, "requires": { "ms": "0.7.2" @@ -5503,14 +5836,16 @@ }, "ms": { "version": "0.7.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", "dev": true } } }, "engine.io-client": { "version": "1.8.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -5529,12 +5864,14 @@ "dependencies": { "component-emitter": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, "debug": { "version": "2.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", "dev": true, "requires": { "ms": "0.7.2" @@ -5542,14 +5879,16 @@ }, "ms": { "version": "0.7.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", "dev": true } } }, "engine.io-parser": { "version": "1.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", "dev": true, "requires": { "after": "0.8.2", @@ -5562,116 +5901,130 @@ }, "ent": { "version": "2.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", "dev": true }, "entities": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", "dev": true }, "error-ex": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "es5-ext": { "version": "0.10.23", - "bundled": true, + "resolved": false, + "integrity": "sha1-dXi1G+l0IHpUh4IbVlOMIk5Oezg=", "dev": true, "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "es6-iterator": "2", + "es6-symbol": "~3.1" } }, "es6-iterator": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "es6-symbol": "^3.1" } }, "es6-map": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "dev": true, "requires": { - "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" + "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" } }, "es6-set": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23", - "es6-iterator": "2.0.1", + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "event-emitter": "~0.3.5" } }, "es6-symbol": { "version": "3.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23" + "d": "1", + "es5-ext": "~0.10.14" } }, "es6-weak-map": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" } }, "escape-html": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "escape-string-regexp": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "escodegen": { "version": "1.8.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { - "esprima": "2.7.3", - "estraverse": "1.9.3", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.2.0" + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" }, "dependencies": { "esprima": { "version": "2.7.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, "estraverse": { "version": "1.9.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", "dev": true }, "source-map": { @@ -5681,347 +6034,386 @@ "dev": true, "optional": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } }, "escope": { "version": "3.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", "dev": true, "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.1.0", - "estraverse": "4.2.0" + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "esformatter": { "version": "0.8.2", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-e6mIKqPtMIOfivds3fTxLaM3084=", + "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" }, "dependencies": { "debug": { "version": "0.7.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", "dev": true }, "espree": { "version": "2.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-32kbkxCIlAKuspzAZnCMVmkLhUs=", "dev": true }, "glob": { "version": "5.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "strip-json-comments": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Fkxk43Coo8wAyeAbU55WmCPw7lQ=", "dev": true }, "supports-color": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-FXWN8J2P87SswwdTn6vicJXhBC0=", "dev": true } } }, "eslint": { "version": "3.19.0", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "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" } }, "espree": { "version": "3.4.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", "dev": true, "requires": { - "acorn": "5.0.3", - "acorn-jsx": "3.0.1" + "acorn": "^5.0.1", + "acorn-jsx": "^3.0.0" } }, "esprima": { "version": "3.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true }, "esquery": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { "version": "4.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-RxO2U2rffyrE8yfVWed1a/9kgiA=", "dev": true, "requires": { - "estraverse": "4.1.1", - "object-assign": "4.1.1" + "estraverse": "~4.1.0", + "object-assign": "^4.0.1" }, "dependencies": { "estraverse": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI=", "dev": true } } }, "estraverse": { "version": "4.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, "esutils": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, "event-emitter": { "version": "0.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23" + "d": "1", + "es5-ext": "~0.10.14" } }, "eventemitter3": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", "dev": true }, "exit": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, "exit-hook": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", "dev": true }, "expand-braces": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", "dev": true, "requires": { - "array-slice": "0.2.3", - "array-unique": "0.2.1", - "braces": "0.1.5" + "array-slice": "^0.2.3", + "array-unique": "^0.2.1", + "braces": "^0.1.2" }, "dependencies": { "braces": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", "dev": true, "requires": { - "expand-range": "0.1.1" + "expand-range": "^0.1.0" } }, "expand-range": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "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": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", "dev": true }, "repeat-string": { "version": "0.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", "dev": true } } }, "expand-brackets": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "expand-range": { "version": "1.8.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.3" + "fill-range": "^2.1.0" } }, "extend": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "dev": true }, "extend-shallow": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "extglob": { "version": "0.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "extsprintf": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", "dev": true }, "fancy-log": { "version": "1.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", "dev": true, "requires": { - "chalk": "1.1.3", - "time-stamp": "1.1.0" + "chalk": "^1.1.1", + "time-stamp": "^1.0.0" } }, "fast-levenshtein": { "version": "2.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "figures": { "version": "1.7.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, "file-entry-cache": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "filename-regex": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", "dev": true }, "fill-range": { "version": "2.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "finalhandler": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk=", "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": { "version": "2.6.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", "dev": true, "requires": { "ms": "2.0.0" @@ -6031,437 +6423,488 @@ }, "find-up": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "first-chunk-stream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", "dev": true }, "flat-cache": { "version": "1.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", "dev": true, "requires": { - "circular-json": "0.3.1", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, "for-in": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "for-own": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "forever-agent": { "version": "0.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, "fork-stream": { "version": "0.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=", "dev": true }, "form-data": { "version": "2.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", "dev": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" } }, "formatio": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", "dev": true, "requires": { - "samsam": "1.1.2" + "samsam": "~1.1" } }, "fs-access": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { - "null-check": "1.0.0" + "null-check": "^1.0.0" } }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "fstream": { "version": "1.0.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "gauge": { "version": "2.7.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "requires": { - "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" + "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" } }, "generate-function": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", "dev": true }, "generate-object-property": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", "dev": true, "requires": { - "is-property": "1.0.2" + "is-property": "^1.0.0" } }, "get-caller-file": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, "get-stdin": { "version": "4.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, "getpass": { "version": "0.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } }, "glob": { "version": "7.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "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" + "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" } }, "glob-base": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" } }, "glob-expand": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-+rNWBjkewYFwPB8KonqHzQW/mjA=", "dev": true, "requires": { - "glob": "4.4.2", - "lodash": "1.2.1" + "glob": "~4.4.2", + "lodash": "1.2.x" }, "dependencies": { "glob": { "version": "4.4.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Pvk+KX7glsG5s/+x0hAlx4q2BUg=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" } }, "lodash": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-7UexbkbwaytAMJto6RY8F+k+owQ=", "dev": true }, "minimatch": { "version": "2.0.10", - "bundled": true, + "resolved": false, + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.0.0" } } } }, "glob-parent": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "globals": { "version": "9.18.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, "globby": { "version": "5.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "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" + "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" } }, "glogg": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", "dev": true, "requires": { - "sparkles": "1.0.0" + "sparkles": "^1.0.0" } }, "graceful-fs": { "version": "4.1.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "graceful-readlink": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, "growl": { "version": "1.9.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", "dev": true }, "gulp-babel-deps": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-BFDjJtT+qrpGo8pkNGeW4sUgGHw=", "dev": true, "requires": { - "babel-deps": "2.1.0", - "gulp-util": "3.0.8", - "through2": "2.0.3", - "vinyl-sourcemaps-apply": "0.2.1" + "babel-deps": "^2.0.0", + "gulp-util": "^3.0.5", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" } }, "gulp-babel-globals": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o7Ou5d5un3FgRM8VZuzkxAE8nps=", "dev": true, "requires": { - "babel-globals": "2.0.1", - "gulp-util": "3.0.8", - "through2": "2.0.3", - "vinyl-sourcemaps-apply": "0.2.1" + "babel-globals": "^2.0.0", + "gulp-util": "^3.0.4", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" } }, "gulp-concat": { "version": "2.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", "dev": true, "requires": { - "concat-with-sourcemaps": "1.0.4", - "through2": "2.0.3", - "vinyl": "2.0.2" + "concat-with-sourcemaps": "^1.0.0", + "through2": "^2.0.0", + "vinyl": "^2.0.0" }, "dependencies": { "clone-stats": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", "dev": true }, "replace-ext": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", "dev": true }, "vinyl": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw=", "dev": true, "requires": { - "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" + "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" } } } }, "gulp-esformatter": { "version": "5.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-n4q6Ut8LuIEO/0/hd5InlNkqWP0=", "dev": true, "requires": { - "esformatter": "0.8.2", - "gulp-util": "3.0.8", - "through2": "2.0.3" + "esformatter": "^0.8.1", + "gulp-util": "^3.0.0", + "through2": "^2.0.0" } }, "gulp-eslint": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-BOV+PhjGl0JnwSz2hV3HF9SjE70=", "dev": true, "requires": { - "bufferstreams": "1.1.1", - "eslint": "3.19.0", - "gulp-util": "3.0.8" + "bufferstreams": "^1.1.1", + "eslint": "^3.0.0", + "gulp-util": "^3.0.6" } }, "gulp-if": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-pJe351cwBQQcqivIt92jyARE1ik=", "dev": true, "requires": { - "gulp-match": "1.0.3", - "ternary-stream": "2.0.1", - "through2": "2.0.3" + "gulp-match": "^1.0.3", + "ternary-stream": "^2.0.1", + "through2": "^2.0.1" } }, "gulp-ignore": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-XC6ioKRALgq0orzRLv2SlTRNePI=", "dev": true, "requires": { - "gulp-match": "1.0.3", - "through2": "2.0.3" + "gulp-match": "^1.0.3", + "through2": "^2.0.1" } }, "gulp-jshint": { "version": "2.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-84KxhWSxBy3vDJqvdTwUba208Og=", "dev": true, "requires": { - "gulp-util": "3.0.8", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "rcloader": "0.2.2", - "through2": "2.0.3" + "gulp-util": "^3.0.0", + "lodash": "^4.12.0", + "minimatch": "^3.0.3", + "rcloader": "^0.2.2", + "through2": "^2.0.0" } }, "gulp-match": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4=", "dev": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.3" } }, "gulp-mocha": { "version": "2.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-HOXrpLlLQMdDav7DxJgsjuqJQZI=", "dev": true, "requires": { - "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-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-rename": { "version": "1.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=", "dev": true }, "gulp-replace": { "version": "0.5.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-aaZ5FLvRPFYr/xT1BKQDeWqg2qk=", "dev": true, "requires": { "istextorbinary": "1.0.2", - "readable-stream": "2.2.11", - "replacestream": "4.0.2" + "readable-stream": "^2.0.1", + "replacestream": "^4.0.0" } }, "gulp-sass": { "version": "2.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-grerkP6QLNw0wE8YDZLyw0kC3VI=", "dev": true, "requires": { - "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-util": "^3.0", + "lodash.clonedeep": "^4.3.2", + "node-sass": "^3.4.2", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" } }, "gulp-sourcemaps": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", "dev": true, "requires": { - "convert-source-map": "1.5.0", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" + "convert-source-map": "^1.1.1", + "graceful-fs": "^4.1.2", + "strip-bom": "^2.0.0", + "through2": "^2.0.0", + "vinyl": "^1.0.0" }, "dependencies": { "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "vinyl": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } } @@ -6469,156 +6912,173 @@ }, "gulp-uglify": { "version": "1.5.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-UkeI2HZm0J+dDCH7IXf5ADmmWMk=", "dev": true, "requires": { - "deap": "1.0.0", - "fancy-log": "1.3.0", - "gulp-util": "3.0.8", - "isobject": "2.1.0", - "through2": "2.0.3", + "deap": "^1.0.0", + "fancy-log": "^1.0.0", + "gulp-util": "^3.0.0", + "isobject": "^2.0.0", + "through2": "^2.0.0", "uglify-js": "2.6.4", - "uglify-save-license": "0.4.1", - "vinyl-sourcemaps-apply": "0.2.1" + "uglify-save-license": "^0.4.1", + "vinyl-sourcemaps-apply": "^0.2.0" } }, "gulp-util": { "version": "3.0.8", - "bundled": true, - "dev": true, - "requires": { - "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", + "resolved": false, + "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", "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl": "0.5.3" + "through2": "^2.0.0", + "vinyl": "^0.5.0" }, "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "object-assign": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", "dev": true } } }, "gulp-wrapper": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-K9PDyFKSHSCepEjqwoEIEd1qK/M=", "dev": true, "requires": { - "gulp-util": "3.0.8", - "through2": "0.6.5" + "gulp-util": "^3.0.4", + "through2": "^0.6.5" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "through2": { "version": "0.6.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } } } }, "gulplog": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "dev": true, "requires": { - "glogg": "1.0.0" + "glogg": "^1.0.0" } }, "handlebars": { "version": "4.0.10", - "bundled": true, + "resolved": false, + "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", "dev": true, "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.6.4" + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" }, "dependencies": { "async": { "version": "1.5.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "source-map": { "version": "0.4.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } }, "har-schema": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", "dev": true }, "har-validator": { "version": "4.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", "dev": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "^4.9.1", + "har-schema": "^1.0.5" } }, "has-ansi": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-binary": { "version": "0.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", "dev": true, "requires": { "isarray": "0.0.1" @@ -6626,440 +7086,503 @@ "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true } } }, "has-color": { "version": "0.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", "dev": true }, "has-cors": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", "dev": true }, "has-flag": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "has-gulplog": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", "dev": true, "requires": { - "sparkles": "1.0.0" + "sparkles": "^1.0.0" } }, "has-unicode": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, "hawk": { "version": "3.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", "dev": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "hoek": { "version": "2.16.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", "dev": true }, "home-or-tmp": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "hosted-git-info": { "version": "2.4.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=", "dev": true }, "htmlparser2": { "version": "3.8.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", "dev": true, "requires": { - "domelementtype": "1.3.0", - "domhandler": "2.3.0", - "domutils": "1.5.1", - "entities": "1.0.0", - "readable-stream": "1.1.14" + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.1.14", - "bundled": true, + "resolved": false, + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "http-errors": { "version": "1.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-X4uO2YrKVFZWv1cplzh/kEpyIlc=", "dev": true, "requires": { "depd": "1.1.0", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": "1.3.1" + "statuses": ">= 1.3.1 < 2" } }, "http-proxy": { "version": "1.16.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", "dev": true, "requires": { - "eventemitter3": "1.2.0", - "requires-port": "1.0.0" + "eventemitter3": "1.x.x", + "requires-port": "1.x.x" } }, "http-signature": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", "dev": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.1" + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "https-proxy-agent": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", "dev": true, "requires": { - "agent-base": "2.1.1", - "debug": "2.6.8", - "extend": "3.0.1" + "agent-base": "2", + "debug": "2", + "extend": "3" } }, "iconv-lite": { "version": "0.4.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", "dev": true }, "iectrl": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-GskwDeZErqpZ7swMsMa/YIESMyo=", "dev": true, "requires": { - "colors": "0.6.2", - "commander": "1.2.0", - "debug": "0.7.4", - "moment": "2.0.0", - "q": "0.9.7" + "colors": "~0.6.0-1", + "commander": "~1.2.0", + "debug": "~0.7.2", + "moment": "~2.0.0", + "q": "~0.9.6" }, "dependencies": { "colors": { "version": "0.6.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", "dev": true }, "commander": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-/VcTv6FTx9bMWZN4patMRcU1Ap4=", "dev": true, "requires": { - "keypress": "0.1.0" + "keypress": "0.1.x" } }, "debug": { "version": "0.7.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", "dev": true } } }, "ignore": { "version": "3.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", "dev": true }, "imurmurhash": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "in-publish": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", "dev": true }, "indent-string": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "indexof": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", "dev": true }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "inquirer": { "version": "0.12.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "dev": true, "requires": { - "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" + "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" } }, "interpret": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", "dev": true }, "invariant": { "version": "2.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", "dev": true, "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, "invert-kv": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "irregular-plurals": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=", "dev": true }, "is-arrayish": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-binary-path": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.8.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { "version": "1.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", "dev": true }, "is-builtin-module": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-dotfile": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", "dev": true }, "is-equal-shallow": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, "is-extglob": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-finite": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-glob": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-my-json-valid": { "version": "2.16.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", "dev": true, "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" } }, "is-number": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-path-cwd": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", "dev": true }, "is-path-in-cwd": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", "dev": true, "requires": { - "is-path-inside": "1.0.0" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-posix-bracket": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", "dev": true }, "is-primitive": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "dev": true }, "is-property": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", "dev": true }, "is-resolvable": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", "dev": true, "requires": { - "tryit": "1.0.3" + "tryit": "^1.0.1" } }, "is-stream": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-typedarray": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, "is-utf8": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-valid-glob": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", "dev": true }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isbinaryfile": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", "dev": true }, "isexe": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isobject": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { "isarray": "1.0.0" @@ -7067,107 +7590,119 @@ }, "isparta": { "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "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" }, "dependencies": { "esprima": { "version": "2.7.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true } } }, "isstream": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "istanbul": { "version": "0.4.5", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "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" }, "dependencies": { "abbrev": { "version": "1.0.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", "dev": true }, "async": { "version": "1.5.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "esprima": { "version": "2.7.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, "glob": { "version": "5.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "resolve": { "version": "1.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true }, "supports-color": { "version": "3.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } }, "istextorbinary": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-rOGTVNGpoBc+/rEITOD4ewrX3s8=", "dev": true, "requires": { - "binaryextensions": "1.0.1", - "textextensions": "1.0.2" + "binaryextensions": "~1.0.0", + "textextensions": "~1.0.0" } }, "jade": { "version": "0.26.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", "dev": true, "requires": { "commander": "0.6.1", @@ -7176,166 +7711,189 @@ "dependencies": { "commander": { "version": "0.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", "dev": true }, "mkdirp": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", "dev": true } } }, "js-base64": { "version": "2.1.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=", "dev": true }, "js-tokens": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=", "dev": true }, "js-yaml": { "version": "3.8.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", "dev": true, "requires": { - "argparse": "1.0.9", - "esprima": "3.1.3" + "argparse": "^1.0.7", + "esprima": "^3.1.1" } }, "js2xmlparser": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WhcPLo1kds5FQF4EgjJCUTeC/jA=", "dev": true }, "jsdoc": { "version": "3.4.3", - "bundled": true, - "dev": true, - "requires": { - "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", + "resolved": false, + "integrity": "sha1-5XQNYUXGgfZnnmwXeDqI292XzNM=", + "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", "taffydb": "2.6.2", - "underscore": "1.8.3" + "underscore": "~1.8.3" }, "dependencies": { "acorn": { "version": "3.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true }, "espree": { "version": "3.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-/V3ux2qXpRIKnNOnyxF3oJI7EdI=", "dev": true, "requires": { - "acorn": "3.3.0", - "acorn-jsx": "3.0.1" + "acorn": "^3.3.0", + "acorn-jsx": "^3.0.0" } } } }, "jsesc": { "version": "0.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true }, "jshint": { "version": "2.9.4", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-XjupeEjVKQJz21FK7kf+JM9ZKTQ=", + "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" }, "dependencies": { "lodash": { "version": "3.7.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", "dev": true }, "shelljs": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", "dev": true }, "strip-json-comments": { "version": "1.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", "dev": true } } }, "jshint-stylish": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-JCCCosA1rgP9gQROBXDMQgjPbmE=", "dev": true, "requires": { - "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" + "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" } }, "json-schema": { "version": "0.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, "json-stable-stringify": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "dev": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stringify-safe": { "version": "5.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "json3": { "version": "3.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", "dev": true }, "json5": { "version": "0.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, "jsonify": { "version": "0.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true }, "jsonpointer": { "version": "4.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", "dev": true }, "jsprim": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", "dev": true, "requires": { "assert-plus": "1.0.0", @@ -7346,1261 +7904,1402 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } }, "karma": { "version": "1.7.0", - "bundled": true, - "dev": true, - "requires": { - "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", + "resolved": false, + "integrity": "sha1-b3oaQGRG+i4YfslTmGmPTO5HYmk=", + "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", "socket.io": "1.7.3", - "source-map": "0.5.6", + "source-map": "^0.5.3", "tmp": "0.0.31", - "useragent": "2.1.13" + "useragent": "^2.1.12" }, "dependencies": { "lodash": { "version": "3.10.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", "dev": true } } }, "karma-babel-preprocessor": { "version": "6.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-euHT5klQ2+EfQht0BAqwj7WmbCE=", "dev": true, "requires": { - "babel-core": "6.25.0" + "babel-core": "^6.0.0" } }, "karma-chai": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", "dev": true }, "karma-chrome-launcher": { "version": "0.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-TG1wDRY6nTTGGO/YeRi+SeekqMk=", "dev": true, "requires": { - "fs-access": "1.0.1", - "which": "1.2.14" + "fs-access": "^1.0.0", + "which": "^1.2.1" } }, "karma-commonjs": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-hoHV19YGYoxfAKNuau88+UPGsKk=", "dev": true }, "karma-coverage": { "version": "0.5.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-sNWLECXVnVxmICYxhvHVj11TSMU=", "dev": true, "requires": { - "dateformat": "1.0.12", - "istanbul": "0.4.5", - "minimatch": "3.0.4", - "source-map": "0.5.6" + "dateformat": "^1.0.6", + "istanbul": "^0.4.0", + "minimatch": "^3.0.0", + "source-map": "^0.5.1" }, "dependencies": { "dateformat": { "version": "1.0.12", - "bundled": true, + "resolved": false, + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", "dev": true, "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" + "get-stdin": "^4.0.1", + "meow": "^3.3.0" } } } }, "karma-firefox-launcher": { "version": "0.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-wF3YZTNpHmLzGVJZUJjovTV9OfM=", "dev": true }, "karma-ievms": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-GhpJDeJY5noKiRO9FSu75bRypIo=", "dev": true, "requires": { - "iectrl": "0.1.2" + "iectrl": "~0.1.0" } }, "karma-mocha": { "version": "0.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-OI7ZF9oV3LGW0bkVwZNO+AMZP44=", "dev": true }, "karma-safari-launcher": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-pjgKzKtgpYP91iT0G5o/EP30EAg=", "dev": true }, "karma-sauce-launcher": { "version": "0.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+kH2r9GtbLdhCIXag8vJkhpNM0w=", "dev": true, "requires": { - "q": "1.5.0", - "sauce-connect-launcher": "0.13.0", - "saucelabs": "1.4.0", - "wd": "0.3.12" + "q": "^1.4.1", + "sauce-connect-launcher": "^0.13.0", + "saucelabs": "^1.0.1", + "wd": "^0.3.4" }, "dependencies": { "q": { "version": "1.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", "dev": true } } }, "karma-sinon": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo=", "dev": true }, "karma-source-map-support": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-G/gee7SwiWJ6s1LsQXnhF8QGpUA=", "dev": true, "requires": { - "source-map-support": "0.4.15" + "source-map-support": "^0.4.1" } }, "keypress": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo=", "dev": true }, "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "^1.1.5" } }, "klaw": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.9" } }, "lazy-cache": { "version": "1.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true }, "lazystream": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-GyXWPHcqTCDwpe0KnXf0hLbhaSA=", "dev": true, "requires": { - "readable-stream": "1.0.34" + "readable-stream": "~1.0.2" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "lcid": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "levn": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "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" } }, "load-json-file": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" }, "dependencies": { "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } } } }, "lodash": { "version": "4.17.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", "dev": true }, "lodash._basecopy": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", "dev": true }, "lodash._basetostring": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", "dev": true }, "lodash._basevalues": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", "dev": true }, "lodash._getnative": { "version": "3.9.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", "dev": true }, "lodash._isiterateecall": { "version": "3.0.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, "lodash._reescape": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", "dev": true }, "lodash._reevaluate": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", "dev": true }, "lodash._reinterpolate": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, "lodash._root": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", "dev": true }, "lodash.assign": { "version": "4.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, "lodash.clonedeep": { "version": "4.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, "lodash.escape": { "version": "3.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", "dev": true, "requires": { - "lodash._root": "3.0.1" + "lodash._root": "^3.0.0" } }, "lodash.isarguments": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", "dev": true }, "lodash.isarray": { "version": "3.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", "dev": true }, "lodash.isequal": { "version": "4.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", "dev": true }, "lodash.isobject": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", "dev": true }, "lodash.keys": { "version": "3.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "dev": true, "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, "lodash.merge": { "version": "4.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=", "dev": true }, "lodash.restparam": { "version": "3.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", "dev": true }, "lodash.template": { "version": "3.6.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", "dev": true, "requires": { - "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._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.templatesettings": { "version": "3.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", "dev": true, "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0" + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" } }, "log-symbols": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "dev": true, "requires": { - "chalk": "1.1.3" + "chalk": "^1.0.0" } }, "log4js": { "version": "0.6.38", - "bundled": true, + "resolved": false, + "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "semver": "4.3.6" + "readable-stream": "~1.0.2", + "semver": "~4.3.3" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "lolex": { "version": "1.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", "dev": true }, "longest": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, "loose-envify": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { - "js-tokens": "3.0.1" + "js-tokens": "^3.0.0" } }, "loud-rejection": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" } }, "lru-cache": { "version": "2.7.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", "dev": true }, "map-obj": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, "marked": { "version": "0.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=", "dev": true }, "media-typer": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, "meow": { "version": "3.7.0", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "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" }, "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, "merge": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", "dev": true }, "merge-stream": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", "dev": true, "requires": { - "readable-stream": "2.2.11" + "readable-stream": "^2.0.1" } }, "metal-jquery-adapter": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZBAgkOA648ZbOQL+s1YGE4nrUQ4=", "dev": true }, "metal-karma-config": { "version": "2.3.1", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "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" } }, "metal-tools-build-amd": { "version": "3.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-fssr0g829V0ILv1wjpAtQJTfXsQ=", "dev": true, "requires": { - "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", + "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", "gulp-sourcemaps": "1.6.0", - "merge": "1.2.0", - "stream-combiner": "0.2.2", - "stream-consume": "0.1.0", - "through2": "2.0.3", - "vinyl-fs": "2.4.4" + "merge": "^1.2.0", + "stream-combiner": "^0.2.2", + "stream-consume": "^0.1.0", + "through2": "^2.0.0", + "vinyl-fs": "^2.2.1" }, "dependencies": { "glob": { "version": "5.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-parent": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" } }, "glob-stream": { "version": "5.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "through2": { "version": "0.6.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } } } }, "is-extglob": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } }, "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "lazystream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { - "readable-stream": "2.2.11" + "readable-stream": "^2.0.5" } }, "ordered-read-streams": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", "dev": true, "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.2.11" + "is-stream": "^1.0.1", + "readable-stream": "^2.0.1" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "unique-stream": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", "dev": true, "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" + "json-stable-stringify": "^1.0.0", + "through2-filter": "^2.0.0" } }, "vinyl": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } }, "vinyl-fs": { "version": "2.4.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, "requires": { - "duplexify": "3.5.0", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", + "duplexify": "^3.2.0", + "glob-stream": "^5.3.2", + "graceful-fs": "^4.0.0", "gulp-sourcemaps": "1.6.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" + "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" } } } }, "metal-tools-build-globals": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Xi9C0yjyzduAYgq5n+0DlzPKGCo=", "dev": true, "requires": { - "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", + "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", "gulp-sourcemaps": "1.6.0", - "merge": "1.2.0", - "stream-combiner": "0.2.2", - "stream-consume": "0.1.0", - "vinyl-fs": "2.4.4" + "merge": "^1.2.0", + "stream-combiner": "^0.2.2", + "stream-consume": "^0.1.0", + "vinyl-fs": "^2.2.1" }, "dependencies": { "glob": { "version": "5.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-parent": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" } }, "glob-stream": { "version": "5.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "through2": { "version": "0.6.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } } } }, "is-extglob": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } }, "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "lazystream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { - "readable-stream": "2.2.11" + "readable-stream": "^2.0.5" } }, "ordered-read-streams": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", "dev": true, "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.2.11" + "is-stream": "^1.0.1", + "readable-stream": "^2.0.1" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "unique-stream": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", "dev": true, "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" + "json-stable-stringify": "^1.0.0", + "through2-filter": "^2.0.0" } }, "vinyl": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } }, "vinyl-fs": { "version": "2.4.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, "requires": { - "duplexify": "3.5.0", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", + "duplexify": "^3.2.0", + "glob-stream": "^5.3.2", + "graceful-fs": "^4.0.0", "gulp-sourcemaps": "1.6.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" + "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" } } } }, "metal-tools-build-jquery": { "version": "2.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-SsuR37qh81TnkIxFV43XCYKWN9c=", "dev": true, "requires": { - "gulp-if": "2.0.2", + "gulp-if": "^2.0.0", "gulp-sourcemaps": "1.6.0", - "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" + "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" }, "dependencies": { "glob": { "version": "5.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-parent": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" } }, "glob-stream": { "version": "5.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "through2": { "version": "0.6.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } } } }, "is-extglob": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } }, "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "lazystream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { - "readable-stream": "2.2.11" + "readable-stream": "^2.0.5" } }, "ordered-read-streams": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", "dev": true, "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.2.11" + "is-stream": "^1.0.1", + "readable-stream": "^2.0.1" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "unique-stream": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", "dev": true, "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" + "json-stable-stringify": "^1.0.0", + "through2-filter": "^2.0.0" } }, "vinyl": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } }, "vinyl-fs": { "version": "2.4.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, "requires": { - "duplexify": "3.5.0", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", + "duplexify": "^3.2.0", + "glob-stream": "^5.3.2", + "graceful-fs": "^4.0.0", "gulp-sourcemaps": "1.6.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" + "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" } } } }, "metal-tools-soy": { "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-IcStv9uqGElx5snccagx05kd/FE=", + "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" }, "dependencies": { "glob": { "version": "5.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-parent": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" } }, "glob-stream": { "version": "5.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "through2": { "version": "0.6.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } } } }, "is-extglob": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-glob": { "version": "3.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } }, "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "lazystream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { - "readable-stream": "2.2.11" + "readable-stream": "^2.0.5" } }, "ordered-read-streams": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", "dev": true, "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.2.11" + "is-stream": "^1.0.1", + "readable-stream": "^2.0.1" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "strip-bom": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "unique-stream": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", "dev": true, "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" + "json-stable-stringify": "^1.0.0", + "through2-filter": "^2.0.0" } }, "vinyl": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } }, "vinyl-fs": { "version": "2.4.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, "requires": { - "duplexify": "3.5.0", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", + "duplexify": "^3.2.0", + "glob-stream": "^5.3.2", + "graceful-fs": "^4.0.0", "gulp-sourcemaps": "1.6.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" + "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" } } } }, "micromatch": { "version": "2.3.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "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" + "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" } }, "mime": { "version": "1.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-WR2E02U6awtKO5343lqoEI5y5eA=", "dev": true }, "mime-db": { "version": "1.27.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", "dev": true }, "mime-types": { "version": "2.1.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", "dev": true, "requires": { - "mime-db": "1.27.0" + "mime-db": "~1.27.0" } }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -8608,7 +9307,8 @@ }, "mocha": { "version": "2.5.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", "dev": true, "requires": { "commander": "2.3.0", @@ -8625,12 +9325,14 @@ "dependencies": { "commander": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", "dev": true }, "debug": { "version": "2.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { "ms": "0.7.1" @@ -8638,62 +9340,72 @@ }, "escape-string-regexp": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", "dev": true }, "glob": { "version": "3.2.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", "dev": true, "requires": { - "inherits": "2.0.3", - "minimatch": "0.3.0" + "inherits": "2", + "minimatch": "0.3" } }, "minimatch": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", "dev": true, "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" + "lru-cache": "2", + "sigmund": "~1.0.0" } }, "ms": { "version": "0.7.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", "dev": true }, "supports-color": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", "dev": true } } }, "moment": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-K7xbRMMhg3aTq278rb1G7ZRiEf4=", "dev": true }, "mout": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-m98dSvV9ZtR8s1OmM1oygQmOFQE=", "dev": true }, "ms": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "mtil": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-oyx1LDas1bAOsEMrJyqh1Cy9kpo=", "dev": true }, "multipipe": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", "dev": true, "requires": { "duplexer2": "0.0.2" @@ -8701,248 +9413,278 @@ }, "mute-stream": { "version": "0.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", "dev": true }, "nan": { "version": "2.6.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", "dev": true }, "natural-compare": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "negotiator": { "version": "0.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "dev": true }, "node-gyp": { "version": "3.6.2", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", + "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" }, "dependencies": { "semver": { "version": "5.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true } } }, "node-int64": { "version": "0.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-LW5rLs5d6FiLQ9iNG8QbJs0fqE0=", "dev": true }, "node-sass": { "version": "3.13.1", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-ckD7v/I5YwS0IjUn7TAgWJwAT8I=", + "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" }, "dependencies": { "gaze": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", "dev": true, "requires": { - "globule": "1.2.0" + "globule": "^1.0.0" } }, "globule": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", "dev": true, "requires": { - "glob": "7.1.2", - "lodash": "4.17.4", - "minimatch": "3.0.4" + "glob": "~7.1.1", + "lodash": "~4.17.4", + "minimatch": "~3.0.2" } } } }, "nomnomnomnom": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "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": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", "dev": true }, "chalk": { "version": "0.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", "dev": true, "requires": { - "ansi-styles": "1.0.0", - "has-color": "0.1.7", - "strip-ansi": "0.1.1" + "ansi-styles": "~1.0.0", + "has-color": "~0.1.0", + "strip-ansi": "~0.1.0" } }, "strip-ansi": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", "dev": true }, "underscore": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", "dev": true } } }, "nopt": { "version": "3.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1.1.0" + "abbrev": "1" } }, "normalize-package-data": { "version": "2.3.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", "dev": true, "requires": { - "hosted-git-info": "2.4.2", - "is-builtin-module": "1.0.0", - "semver": "4.3.6", - "validate-npm-package-license": "3.0.1" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.0.2" + "remove-trailing-separator": "^1.0.1" } }, "npm-path": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-BHSuAEGcMn1UcBt88s0F3Ii+EUA=", "dev": true, "requires": { - "which": "1.2.14" + "which": "^1.2.4" } }, "npm-run": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-KN/ArV4uRv4ISOK9WN3wAue3PBU=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, "npm-which": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DEaYIWC3gwk2YdHQG9RJbS/qu6w=", "dev": true, "requires": { - "commander": "2.9.0", - "npm-path": "1.1.0", - "which": "1.2.14" + "commander": "^2.2.0", + "npm-path": "^1.0.0", + "which": "^1.0.5" } }, "npmlog": { "version": "4.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==", "dev": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "null-check": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", "dev": true }, "number-is-nan": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "oauth-sign": { "version": "0.8.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", "dev": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-component": { "version": "0.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", "dev": true }, "object.omit": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "on-finished": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "requires": { "ee-first": "1.1.1" @@ -8950,310 +9692,357 @@ }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, "open": { "version": "0.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=", "dev": true }, "optimist": { "version": "0.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" }, "dependencies": { "wordwrap": { "version": "0.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true } } }, "optionator": { "version": "0.8.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "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" + "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" } }, "options": { "version": "0.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", "dev": true }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { - "lcid": "1.0.0" + "lcid": "^1.0.0" } }, "os-shim": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", "dev": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "osenv": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "parse-glob": { "version": "3.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-json": { "version": "2.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "parsejson": { "version": "0.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", "dev": true, "requires": { - "better-assert": "1.0.2" + "better-assert": "~1.0.0" } }, "parseqs": { "version": "0.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "dev": true, "requires": { - "better-assert": "1.0.2" + "better-assert": "~1.0.0" } }, "parseuri": { "version": "0.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "dev": true, "requires": { - "better-assert": "1.0.2" + "better-assert": "~1.0.0" } }, "parseurl": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", "dev": true }, "path-dirname": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, "path-exists": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-is-inside": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "path-parse": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, "path-type": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "performance-now": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", "dev": true }, "pify": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "plur": { "version": "2.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", "dev": true, "requires": { - "irregular-plurals": "1.2.0" + "irregular-plurals": "^1.0.0" } }, "pluralize": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", "dev": true }, "prelude-ls": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "preserve": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, "private": { "version": "0.1.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", "dev": true }, "process-nextick-args": { "version": "1.0.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "progress": { "version": "1.1.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true }, "protochain": { "version": "1.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-mRxAfpneJkqt+PgVBLXn+ve/omA=", "dev": true }, "pseudomap": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "punycode": { "version": "1.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, "q": { "version": "0.9.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-TeLmyzspCIyeTLwDv51C+5bOL3U=", "dev": true }, "qjobs": { "version": "1.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZZ3p8s+NzCehSBJ28gU3cnI4LnM=", "dev": true }, "qs": { "version": "6.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", "dev": true }, "randomatic": { "version": "1.1.7", - "bundled": true, + "resolved": false, + "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": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { "version": "3.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "^1.1.5" } } } }, "kind-of": { "version": "4.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "^1.1.5" } } } }, "range-parser": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", "dev": true }, "raw-body": { "version": "2.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", "dev": true, "requires": { "bytes": "2.4.0", @@ -9263,401 +10052,450 @@ }, "rcfinder": { "version": "0.1.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-8+gPOH3fmugK4wpBADKWQuroERU=", "dev": true, "requires": { - "lodash.clonedeep": "4.5.0" + "lodash.clonedeep": "^4.3.2" } }, "rcloader": { "version": "0.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-WNIpi0YtC5v9ITPSoex0+9cFxxc=", "dev": true, "requires": { - "lodash.assign": "4.2.0", - "lodash.isobject": "3.0.2", - "lodash.merge": "4.6.0", - "rcfinder": "0.1.9" + "lodash.assign": "^4.2.0", + "lodash.isobject": "^3.0.2", + "lodash.merge": "^4.6.0", + "rcfinder": "^0.1.6" } }, "read-pkg": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.3.8", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "readable-stream": { "version": "2.2.11", - "bundled": true, + "resolved": false, + "integrity": "sha512-h+8+r3MKEhkiVrwdKL8aWs1oc1VvBu33ueshOvS26RsZQ3Amhx/oO3TKe4lApSV9ueY6as8EAh7mtuFjdlhg9Q==", "dev": true, "requires": { - "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" + "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" } }, "readdirp": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.2.11", - "set-immediate-shim": "1.0.1" + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" } }, "readline2": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", "mute-stream": "0.0.5" } }, "rechoir": { "version": "0.6.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "resolve": "1.3.3" + "resolve": "^1.1.6" } }, "redent": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "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": { "version": "1.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", "dev": true }, "regenerator-runtime": { "version": "0.10.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", "dev": true }, "regenerator-transform": { "version": "0.9.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "private": "0.1.7" + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" } }, "regex-cache": { "version": "0.4.3", - "bundled": true, + "resolved": false, + "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" } }, "regexpu-core": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "1.3.2", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "regjsgen": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", "dev": true }, "regjsparser": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } }, "remove-trailing-separator": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", "dev": true }, "repeat-element": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", "dev": true }, "repeat-string": { "version": "1.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "repeating": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "replace-ext": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", "dev": true }, "replacestream": { "version": "4.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-DEFAcH5PAyP1DeBEhRcIz1i8N70=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1", - "readable-stream": "2.2.11" + "escape-string-regexp": "^1.0.3", + "object-assign": "^4.0.1", + "readable-stream": "^2.0.2" } }, "request": { "version": "2.81.0", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "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" } }, "require-directory": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "require-uncached": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" } }, "requires-port": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, "requizzle": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=", "dev": true, "requires": { - "underscore": "1.6.0" + "underscore": "~1.6.0" }, "dependencies": { "underscore": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", "dev": true } } }, "resolve": { "version": "1.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", "dev": true, "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, "resolve-from": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", "dev": true }, "restore-cursor": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "dev": true, "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, "right-align": { "version": "0.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "requires": { - "align-text": "0.1.4" + "align-text": "^0.1.1" } }, "rimraf": { "version": "2.6.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "rocambole": { "version": "0.7.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9seVBVF9xCtvuECEK4uVOw+WhYU=", "dev": true, "requires": { - "esprima": "2.7.3" + "esprima": "^2.1" }, "dependencies": { "esprima": { "version": "2.7.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true } } }, "rocambole-indent": { "version": "2.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-oYokl3ygQAuGHapGMehh3LUtCFw=", "dev": true, "requires": { - "debug": "2.6.8", - "mout": "0.11.1", - "rocambole-token": "1.2.1" + "debug": "^2.1.3", + "mout": "^0.11.0", + "rocambole-token": "^1.2.1" }, "dependencies": { "mout": { "version": "0.11.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=", "dev": true } } }, "rocambole-linebreak": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-A2IVFbQ7RyHJflocG8paA2Y2jy8=", "dev": true, "requires": { - "debug": "2.6.8", - "rocambole-token": "1.2.1", - "semver": "4.3.6" + "debug": "^2.1.3", + "rocambole-token": "^1.2.1", + "semver": "^4.3.1" } }, "rocambole-node": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-21tJ3nQHsAgN1RSHLyjjk9D3/z8=", "dev": true }, "rocambole-token": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-x4XfdCjcPLJ614lwR71SOMwHDTU=", "dev": true }, "rocambole-whitespace": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YzMJSSVrKZQfWbGQRZ+ZnGsdO/k=", "dev": true, "requires": { - "debug": "2.6.8", - "repeat-string": "1.6.1", - "rocambole-token": "1.2.1" + "debug": "^2.1.3", + "repeat-string": "^1.5.0", + "rocambole-token": "^1.2.1" } }, "run-async": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", "dev": true, "requires": { - "once": "1.4.0" + "once": "^1.3.0" } }, "run-sequence": { "version": "1.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-UJWgvr6YczsBQL0I3YDsAw3azes=", "dev": true, "requires": { - "chalk": "1.1.3", - "gulp-util": "3.0.8" + "chalk": "*", + "gulp-util": "*" } }, "rx-lite": { "version": "3.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", "dev": true }, "safe-buffer": { "version": "5.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", "dev": true }, "samsam": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=", "dev": true }, "sass-graph": { "version": "2.2.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", "dev": true, "requires": { - "glob": "7.1.2", - "lodash": "4.17.4", - "scss-tokenizer": "0.2.3", - "yargs": "7.1.0" + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^7.0.0" } }, "sauce-connect-launcher": { "version": "0.13.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-JdffnaFqXtHKoT30JMtXywttWiI=", "dev": true, "requires": { - "adm-zip": "0.4.7", + "adm-zip": "~0.4.3", "async": "1.4.0", "lodash": "3.10.1", "rimraf": "2.4.3" @@ -9665,143 +10503,163 @@ "dependencies": { "async": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Nfhvg8WeBCHQmc2akdgnj7V4wA0=", "dev": true }, "glob": { "version": "5.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "lodash": { "version": "3.10.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", "dev": true }, "rimraf": { "version": "2.4.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-5bUclDekxYKtuVXp8oz42UXicq8=", "dev": true, "requires": { - "glob": "5.0.15" + "glob": "^5.0.14" } } } }, "saucelabs": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-uTSpr52ih0s/QKrh/N5QpEZvXzg=", "dev": true, "requires": { - "https-proxy-agent": "1.0.0" + "https-proxy-agent": "^1.0.0" } }, "scss-tokenizer": { "version": "0.2.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", "dev": true, "requires": { - "js-base64": "2.1.9", - "source-map": "0.4.4" + "js-base64": "^2.1.8", + "source-map": "^0.4.2" }, "dependencies": { "source-map": { "version": "0.4.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } }, "semver": { "version": "4.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", "dev": true }, "serializerr": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-EtTFqhw/+49tHcXzlaqUVVacP5E=", "dev": true, "requires": { - "protochain": "1.0.5" + "protochain": "^1.0.5" } }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "set-immediate-shim": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", "dev": true }, "setprototypeof": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", "dev": true }, "shelljs": { "version": "0.7.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true, "requires": { - "glob": "7.1.2", - "interpret": "1.0.3", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "sigmund": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "sinon": { "version": "1.17.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", "dev": true, "requires": { "formatio": "1.1.1", "lolex": "1.3.2", "samsam": "1.1.2", - "util": "0.10.3" + "util": ">=0.10.3 <1" } }, "slash": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, "slice-ansi": { "version": "0.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, "sntp": { "version": "1.0.9", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", "dev": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "socket.io": { "version": "1.7.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", "dev": true, "requires": { "debug": "2.3.3", @@ -9815,7 +10673,8 @@ "dependencies": { "debug": { "version": "2.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", "dev": true, "requires": { "ms": "0.7.2" @@ -9823,19 +10682,22 @@ }, "ms": { "version": "0.7.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", "dev": true }, "object-assign": { "version": "4.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", "dev": true } } }, "socket.io-adapter": { "version": "0.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", "dev": true, "requires": { "debug": "2.3.3", @@ -9844,7 +10706,8 @@ "dependencies": { "debug": { "version": "2.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", "dev": true, "requires": { "ms": "0.7.2" @@ -9852,14 +10715,16 @@ }, "ms": { "version": "0.7.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", "dev": true } } }, "socket.io-client": { "version": "1.7.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", "dev": true, "requires": { "backo2": "1.0.2", @@ -9877,12 +10742,14 @@ "dependencies": { "component-emitter": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, "debug": { "version": "2.3.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", "dev": true, "requires": { "ms": "0.7.2" @@ -9890,14 +10757,16 @@ }, "ms": { "version": "0.7.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", "dev": true } } }, "socket.io-parser": { "version": "2.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", "dev": true, "requires": { "component-emitter": "1.1.2", @@ -9908,7 +10777,8 @@ "dependencies": { "debug": { "version": "2.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { "ms": "0.7.1" @@ -9916,507 +10786,577 @@ }, "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "ms": { "version": "0.7.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", "dev": true } } }, "source-map": { "version": "0.5.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", "dev": true }, "source-map-support": { "version": "0.4.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "^0.5.6" } }, "soyparser": { "version": "0.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-ieDvf/LaANbvGPPkU47oQNtKDOY=", "dev": true, "requires": { - "merge": "1.2.0", - "tunic": "1.0.0" + "merge": "^1.2.0", + "tunic": "^1.0.0" } }, "sparkles": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", "dev": true }, "spawn-sync": { "version": "1.0.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", "dev": true, "requires": { - "concat-stream": "1.6.0", - "os-shim": "0.1.3" + "concat-stream": "^1.4.7", + "os-shim": "^0.1.2" } }, "spdx-correct": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-license-ids": "^1.0.2" } }, "spdx-expression-parse": { "version": "1.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", "dev": true }, "spdx-license-ids": { "version": "1.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", "dev": true }, "sprintf-js": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "sshpk": { "version": "1.13.1", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "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" }, "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } }, "statuses": { "version": "1.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", "dev": true }, "stdin": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0wQZgarsPf28d6GzjWNy449ftx4=", "dev": true }, "stream-combiner": { "version": "0.2.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", "dev": true, "requires": { - "duplexer": "0.1.1", - "through": "2.3.8" + "duplexer": "~0.1.1", + "through": "~2.3.4" } }, "stream-consume": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", "dev": true }, "stream-shift": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, "string-length": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", "dev": true, "requires": { - "strip-ansi": "3.0.1" + "strip-ansi": "^3.0.0" } }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", "dev": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "~5.0.1" } }, "stringstream": { "version": "0.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", "dev": true }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-bom-stream": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", "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": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } } } }, "strip-indent": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "4.0.1" + "get-stdin": "^4.0.1" } }, "strip-json-comments": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "supports-color": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, "sync-exec": { "version": "0.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-P3JY5KW6FyRTgZCfpqb2z1BuFmE=", "dev": true }, "table": { "version": "3.8.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "dev": true, "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", "slice-ansi": "0.0.4", - "string-width": "2.0.0" + "string-width": "^2.0.0" }, "dependencies": { "is-fullwidth-code-point": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "3.0.1" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^3.0.0" } } } }, "taffydb": { "version": "2.6.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", "dev": true }, "tar": { "version": "2.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-stream": { "version": "1.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-vpIYwTDCACnhB7D5Z/sj3gV50Tw=", "dev": true, "requires": { - "bl": "0.9.5", - "end-of-stream": "1.4.0", - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "bl": "^0.9.0", + "end-of-stream": "^1.0.0", + "readable-stream": "~1.0.33", + "xtend": "^4.0.0" }, "dependencies": { "end-of-stream": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", "dev": true, "requires": { - "once": "1.4.0" + "once": "^1.4.0" } }, "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "temp": { "version": "0.8.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", "dev": true, "requires": { - "os-tmpdir": "1.0.2", - "rimraf": "2.2.8" + "os-tmpdir": "^1.0.0", + "rimraf": "~2.2.6" }, "dependencies": { "rimraf": { "version": "2.2.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", "dev": true } } }, "ternary-stream": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-Bk5Im0tb9gumpre8fy9cJ07Pgmk=", "dev": true, "requires": { - "duplexify": "3.5.0", - "fork-stream": "0.0.4", - "merge-stream": "1.0.1", - "through2": "2.0.3" + "duplexify": "^3.5.0", + "fork-stream": "^0.0.4", + "merge-stream": "^1.0.0", + "through2": "^2.0.1" } }, "text-table": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "textextensions": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZUhjk+4fK7A5pgy7oFsLaL2VAdI=", "dev": true }, "through": { "version": "2.3.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "through2": { "version": "2.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "2.2.11", - "xtend": "4.0.1" + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" } }, "through2-filter": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", "dev": true, "requires": { - "through2": "2.0.3", - "xtend": "4.0.1" + "through2": "~2.0.0", + "xtend": "~4.0.0" } }, "time-stamp": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", "dev": true }, "tmp": { "version": "0.0.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.1" } }, "to-absolute-glob": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", "dev": true, "requires": { - "extend-shallow": "2.0.1" + "extend-shallow": "^2.0.1" } }, "to-array": { "version": "0.1.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", "dev": true }, "to-fast-properties": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, "to-iso-string": { "version": "0.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", "dev": true }, "tough-cookie": { "version": "2.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", "dev": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "trim-newlines": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true }, "trim-right": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, "tryit": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", "dev": true }, "tunic": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-CllFzgeG8GNK84ViFPbdjKTS3/g=", "dev": true, "requires": { - "mout": "0.11.1", - "mtil": "0.1.3" + "mout": "^0.11.0", + "mtil": "^0.1.3" }, "dependencies": { "mout": { "version": "0.11.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=", "dev": true } } }, "tunnel-agent": { "version": "0.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "type-check": { "version": "0.3.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "type-detect": { "version": "0.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", "dev": true }, "type-is": { "version": "1.6.15", - "bundled": true, + "resolved": false, + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.15" + "mime-types": "~2.1.15" } }, "typedarray": { "version": "0.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "uglify-js": { "version": "2.6.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", "dev": true, "requires": { - "async": "0.2.10", - "source-map": "0.5.6", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "async": "~0.2.6", + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" }, "dependencies": { "camelcase": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true }, "cliui": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", + "center-align": "^0.1.1", + "right-align": "^0.1.1", "wordwrap": "0.0.2" } }, "wordwrap": { "version": "0.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true }, "yargs": { "version": "3.10.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", "window-size": "0.1.0" } } @@ -10424,27 +11364,32 @@ }, "uglify-save-license": { "version": "0.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=", "dev": true }, "uglify-to-browserify": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true }, "ultron": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", "dev": true }, "underscore": { "version": "1.8.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", "dev": true }, "underscore-contrib": { "version": "0.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZltmwkeD+PorGMn4y7Dix9SMJsc=", "dev": true, "requires": { "underscore": "1.6.0" @@ -10452,48 +11397,55 @@ "dependencies": { "underscore": { "version": "1.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", "dev": true } } }, "underscore.string": { "version": "3.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Rhe4waJQz25QZPu7Nj0PqWzxRVI=", "dev": true }, "unpipe": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true }, "user-home": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.0" } }, "useragent": { "version": "2.1.13", - "bundled": true, + "resolved": false, + "integrity": "sha1-u6Q+iqJNXOuDwpN0c+EC4h33TBA=", "dev": true, "requires": { - "lru-cache": "2.2.4", - "tmp": "0.0.31" + "lru-cache": "2.2.x", + "tmp": "0.0.x" }, "dependencies": { "lru-cache": { "version": "2.2.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=", "dev": true } } }, "util": { "version": "0.10.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { "inherits": "2.0.1" @@ -10501,48 +11453,56 @@ "dependencies": { "inherits": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", "dev": true } } }, "util-deprecate": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "utils-merge": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", "dev": true }, "uuid": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", "dev": true }, "vali-date": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", "dev": true }, "validate-npm-package-license": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" } }, "vargs": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8=", "dev": true }, "verror": { "version": "1.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", "dev": true, "requires": { "extsprintf": "1.0.2" @@ -10550,74 +11510,85 @@ }, "vinyl": { "version": "0.5.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } }, "vinyl-sourcemaps-apply": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "^0.5.1" } }, "void-elements": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", "dev": true }, "wd": { "version": "0.3.12", - "bundled": true, + "resolved": false, + "integrity": "sha1-P7Tx11n4yF3eU5PRczT/4D6bsyk=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "asn1": { "version": "0.1.11", - "bundled": true, + "resolved": false, + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", "dev": true }, "assert-plus": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", "dev": true }, "async": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=", "dev": true }, "aws-sign2": { "version": "0.5.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", "dev": true }, "bluebird": { "version": "2.11.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", "dev": true }, "caseless": { "version": "0.9.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-t7Zc5r8UE4hlOc/VM/CzDv+pz4g=", "dev": true }, "combined-stream": { "version": "0.0.7", - "bundled": true, + "resolved": false, + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", "dev": true, "requires": { "delayed-stream": "0.0.5" @@ -10625,296 +11596,335 @@ }, "delayed-stream": { "version": "0.0.5", - "bundled": true, + "resolved": false, + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", "dev": true }, "form-data": { "version": "0.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=", "dev": true, "requires": { - "async": "0.9.2", - "combined-stream": "0.0.7", - "mime-types": "2.0.14" + "async": "~0.9.0", + "combined-stream": "~0.0.4", + "mime-types": "~2.0.3" }, "dependencies": { "async": { "version": "0.9.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", "dev": true } } }, "har-validator": { "version": "1.8.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-2DhCsOtMQ1lgrrEIoGejqpTA7rI=", "dev": true, "requires": { - "bluebird": "2.11.0", - "chalk": "1.1.3", - "commander": "2.9.0", - "is-my-json-valid": "2.16.0" + "bluebird": "^2.9.30", + "chalk": "^1.0.0", + "commander": "^2.8.1", + "is-my-json-valid": "^2.12.0" } }, "hawk": { "version": "2.3.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-HnMc45RH+h0PbXB/e87r7A/R7B8=", "dev": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "http-signature": { "version": "0.10.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", "dev": true, "requires": { "asn1": "0.1.11", - "assert-plus": "0.1.5", + "assert-plus": "^0.1.5", "ctype": "0.5.3" } }, "lodash": { "version": "3.9.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-AVnoaDL+/8bWHYUrEqlTuZSWvTI=", "dev": true }, "mime-db": { "version": "1.12.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=", "dev": true }, "mime-types": { "version": "2.0.14", - "bundled": true, + "resolved": false, + "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", "dev": true, "requires": { - "mime-db": "1.12.0" + "mime-db": "~1.12.0" } }, "node-uuid": { "version": "1.4.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", "dev": true }, "oauth-sign": { "version": "0.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-fb6uRPbKRU4fFoRR1jB0ZzWBPOM=", "dev": true }, "q": { "version": "1.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", "dev": true }, "qs": { "version": "2.4.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-9854jld33wtQENp/fE5zujJHD1o=", "dev": true }, "request": { "version": "2.55.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-11wc32eddrsQD5v/4f5VG1wk6T0=", "dev": true, "requires": { - "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" + "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" } }, "tunnel-agent": { "version": "0.4.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", "dev": true } } }, "which": { "version": "1.2.14", - "bundled": true, + "resolved": false, + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "which-module": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, "wide-align": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "window-size": { "version": "0.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true }, "wordwrap": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "wrap-ansi": { "version": "2.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" } }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write": { "version": "0.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "ws": { "version": "1.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", "dev": true, "requires": { - "options": "0.0.6", - "ultron": "1.0.2" + "options": ">=0.0.5", + "ultron": "1.0.x" } }, "wtf-8": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", "dev": true }, "xmlhttprequest-ssl": { "version": "1.5.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", "dev": true }, "xtend": { "version": "4.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, "y18n": { "version": "3.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, "yallist": { "version": "2.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { "version": "7.1.0", - "bundled": true, - "dev": true, - "requires": { - "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" + "resolved": false, + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "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" }, "dependencies": { "camelcase": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true } } }, "yargs-parser": { "version": "5.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", "dev": true, "requires": { - "camelcase": "3.0.0" + "camelcase": "^3.0.0" }, "dependencies": { "camelcase": { "version": "3.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true } } }, "yeast": { "version": "0.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", "dev": true }, "zip-stream": { "version": "0.5.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-Mty8UG0Nq00hNyYlvX66rDwv/1Y=", "dev": true, "requires": { - "compress-commons": "0.2.9", - "lodash": "3.2.0", - "readable-stream": "1.0.34" + "compress-commons": "~0.2.0", + "lodash": "~3.2.0", + "readable-stream": "~1.0.26" }, "dependencies": { "isarray": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "lodash": { "version": "3.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-S/UKMkP5rrC6xBpV09WZBnWkYvs=", "dev": true }, "readable-stream": { "version": "1.0.34", - "bundled": true, + "resolved": false, + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", - "bundled": true, + "resolved": false, + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } @@ -10933,18 +11943,18 @@ "integrity": "sha1-fMzomaijv8oVk6M0jQ+/Qd0/UeU=", "dev": true, "requires": { - "@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" + "@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" }, "dependencies": { "acorn": { @@ -10959,8 +11969,8 @@ "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } } @@ -10972,9 +11982,9 @@ "integrity": "sha1-XVawCEUu32gj2t7LPmJU0G87XT0=", "dev": true, "requires": { - "gulp-util": "3.0.8", - "strip-debug": "1.1.1", - "through2": "2.0.3" + "gulp-util": "^3.0.0", + "strip-debug": "^1.0.0", + "through2": "^2.0.0" } }, "gulp-template": { @@ -10983,9 +11993,9 @@ "integrity": "sha1-Bd42gIxvuZZleNWpTucs7gjNxTs=", "dev": true, "requires": { - "gulp-util": "3.0.8", - "lodash": "4.17.4", - "through2": "2.0.3" + "gulp-util": "^3.0.0", + "lodash": "^4.8.2", + "through2": "^2.0.0" } }, "gulp-util": { @@ -10994,24 +12004,24 @@ "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", "dev": true, "requires": { - "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", + "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", "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl": "0.5.3" + "through2": "^2.0.0", + "vinyl": "^0.5.0" }, "dependencies": { "minimist": { @@ -11034,7 +12044,7 @@ "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "dev": true, "requires": { - "glogg": "1.0.0" + "glogg": "^1.0.0" } }, "handlebars": { @@ -11043,10 +12053,10 @@ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" }, "dependencies": { "source-map": { @@ -11055,7 +12065,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -11066,7 +12076,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-color": { @@ -11087,7 +12097,7 @@ "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", "dev": true, "requires": { - "sparkles": "1.0.0" + "sparkles": "^1.0.0" } }, "home-or-tmp": { @@ -11096,8 +12106,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "homedir-polyfill": { @@ -11106,7 +12116,7 @@ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", "dev": true, "requires": { - "parse-passwd": "1.0.0" + "parse-passwd": "^1.0.0" } }, "hosted-git-info": { @@ -11121,12 +12131,12 @@ "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", "dev": true, "requires": { - "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" + "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" } }, "http-errors": { @@ -11135,8 +12145,8 @@ "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", "dev": true, "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" + "inherits": "~2.0.1", + "statuses": "1" } }, "iconv-lite": { @@ -11163,7 +12173,7 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "inflight": { @@ -11172,8 +12182,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -11194,8 +12204,8 @@ "integrity": "sha1-6QBeW7kCXMmpvo5ErYf4rViIyB0=", "dev": true, "requires": { - "moment": "2.18.1", - "sanitize-html": "1.14.1" + "moment": "^2.14.1", + "sanitize-html": "^1.13.0" } }, "inquirer": { @@ -11204,19 +12214,19 @@ "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "dev": true, "requires": { - "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" + "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" } }, "interpret": { @@ -11231,7 +12241,7 @@ "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", "dev": true, "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, "is-absolute": { @@ -11240,8 +12250,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 +12267,7 @@ "dev": true, "optional": true, "requires": { - "binary-extensions": "1.9.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -11272,7 +12282,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-dotfile": { @@ -11287,7 +12297,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -11308,7 +12318,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -11317,7 +12327,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-glob": { @@ -11326,7 +12336,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-my-json-valid": { @@ -11335,10 +12345,10 @@ "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", "dev": true, "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" } }, "is-number": { @@ -11347,7 +12357,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-path-cwd": { @@ -11362,7 +12372,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 +12381,7 @@ "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -11380,7 +12390,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -11421,7 +12431,7 @@ "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", "dev": true, "requires": { - "is-unc-path": "0.1.2" + "is-unc-path": "^0.1.1" } }, "is-resolvable": { @@ -11430,7 +12440,7 @@ "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", "dev": true, "requires": { - "tryit": "1.0.3" + "tryit": "^1.0.1" } }, "is-unc-path": { @@ -11439,7 +12449,7 @@ "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", "dev": true, "requires": { - "unc-path-regex": "0.1.2" + "unc-path-regex": "^0.1.0" } }, "is-utf8": { @@ -11481,15 +12491,15 @@ "integrity": "sha1-HekZlvSAsi3LGsqFECVbrhV0RG4=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "esprima": { @@ -11506,20 +12516,20 @@ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "escodegen": { @@ -11528,11 +12538,11 @@ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { - "esprima": "2.7.3", - "estraverse": "1.9.3", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.2.0" + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" } }, "esprima": { @@ -11553,11 +12563,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "resolve": { @@ -11573,7 +12583,7 @@ "dev": true, "optional": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } }, "supports-color": { @@ -11582,7 +12592,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } @@ -11629,8 +12639,8 @@ "integrity": "sha512-0LoUNELX4S+iofCT8f4uEHIiRBR+c2AINyC8qRWfC6QNruLtxVZRJaPcu/xwMgFIgDxF25tGHaDjvxzJCNE9yw==", "dev": true, "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "js2xmlparser": { @@ -11639,7 +12649,7 @@ "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=", "dev": true, "requires": { - "xmlcreate": "1.0.2" + "xmlcreate": "^1.0.1" } }, "jsbn": { @@ -11655,18 +12665,18 @@ "integrity": "sha512-K9mjBmCm2P62kqJ5UU6Zj7zZnJoLxZBzgLm2yVv98tqLHYSpIvxUkM+dGBua+yUsvOhXsAh232a/joE+86D4CQ==", "dev": true, "requires": { - "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", + "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", "taffydb": "2.6.2", - "underscore": "1.8.3" + "underscore": "~1.8.3" }, "dependencies": { "babylon": { @@ -11689,7 +12699,7 @@ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "dev": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json5": { @@ -11704,7 +12714,7 @@ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "jsonify": { @@ -11725,7 +12735,7 @@ "integrity": "sha1-euHT5klQ2+EfQht0BAqwj7WmbCE=", "dev": true, "requires": { - "babel-core": "6.25.0" + "babel-core": "^6.0.0" } }, "karma-chai": { @@ -11740,8 +12750,8 @@ "integrity": "sha1-TG1wDRY6nTTGGO/YeRi+SeekqMk=", "dev": true, "requires": { - "fs-access": "1.0.1", - "which": "1.2.14" + "fs-access": "^1.0.0", + "which": "^1.2.1" } }, "karma-commonjs": { @@ -11756,10 +12766,10 @@ "integrity": "sha1-sNWLECXVnVxmICYxhvHVj11TSMU=", "dev": true, "requires": { - "dateformat": "1.0.12", - "istanbul": "0.4.5", - "minimatch": "3.0.4", - "source-map": "0.5.6" + "dateformat": "^1.0.6", + "istanbul": "^0.4.0", + "minimatch": "^3.0.0", + "source-map": "^0.5.1" }, "dependencies": { "dateformat": { @@ -11768,8 +12778,8 @@ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", "dev": true, "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" + "get-stdin": "^4.0.1", + "meow": "^3.3.0" } } } @@ -11792,7 +12802,7 @@ "integrity": "sha1-G/gee7SwiWJ6s1LsQXnhF8QGpUA=", "dev": true, "requires": { - "source-map-support": "0.4.15" + "source-map-support": "^0.4.1" } }, "kind-of": { @@ -11801,7 +12811,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "^1.1.5" } }, "klaw": { @@ -11810,7 +12820,7 @@ "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.9" } }, "lazy-cache": { @@ -11826,8 +12836,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 +12846,15 @@ "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", "dev": true, "requires": { - "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" + "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" } }, "livereload-js": { @@ -11859,11 +12869,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" }, "dependencies": { "strip-bom": { @@ -11872,7 +12882,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } } } @@ -11943,7 +12953,7 @@ "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", "dev": true, "requires": { - "lodash._root": "3.0.1" + "lodash._root": "^3.0.0" } }, "lodash.isarguments": { @@ -11976,9 +12986,9 @@ "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "dev": true, "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, "lodash.mapvalues": { @@ -11999,15 +13009,15 @@ "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", "dev": true, "requires": { - "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._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.templatesettings": { @@ -12016,8 +13026,8 @@ "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", "dev": true, "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0" + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" } }, "lolex": { @@ -12038,7 +13048,7 @@ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { - "js-tokens": "3.0.2" + "js-tokens": "^3.0.0" } }, "loud-rejection": { @@ -12047,8 +13057,8 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" } }, "lru-cache": { @@ -12063,7 +13073,7 @@ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", "dev": true, "requires": { - "es5-ext": "0.10.24" + "es5-ext": "~0.10.2" } }, "map-cache": { @@ -12102,14 +13112,14 @@ "integrity": "sha1-G8PqHkvgVt1HXVIZede+PV5bIcg=", "dev": true, "requires": { - "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" + "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" } }, "meow": { @@ -12118,16 +13128,16 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "minimist": { @@ -12154,9 +13164,9 @@ "resolved": "https://registry.npmjs.org/metal-ajax/-/metal-ajax-2.1.1.tgz", "integrity": "sha512-r61ku32uivdaBd3joWrTiGV2kyG9Nvpt4gq4Npo/9MDWj2Tcm4xk2PZ7iKpIAF88JD4dwW+etjgK5Il3SzC9+g==", "requires": { - "metal": "2.16.5", - "metal-promise": "2.0.1", - "metal-uri": "2.2.6" + "metal": "^2.0.0", + "metal-promise": "^2.0.0", + "metal-uri": "^2.0.0" } }, "metal-debounce": { @@ -12169,8 +13179,8 @@ "resolved": "https://registry.npmjs.org/metal-dom/-/metal-dom-2.16.8.tgz", "integrity": "sha512-wmLcuaJ63W/LMT/GgZhqpUefFOVDXlQLI+NJvHJUduIc1XSQOEpSH3OTlzxFsNeMxWEzeC2VAZuKJlrIjNQvDA==", "requires": { - "metal": "2.16.8", - "metal-events": "2.16.8" + "metal": "^2.16.8", + "metal-events": "^2.16.8" }, "dependencies": { "metal": { @@ -12183,7 +13193,7 @@ "resolved": "https://registry.npmjs.org/metal-events/-/metal-events-2.16.8.tgz", "integrity": "sha512-Aa9ozlChOuJT0rLMSSpV7V+0RAk+TGhoe8Khlqh9iaJUPWlofptpgTTlagoqNxTm13iFNm6b2+mZauWM65iBlQ==", "requires": { - "metal": "2.16.8" + "metal": "^2.16.8" } } } @@ -12193,7 +13203,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": { @@ -12202,20 +13212,20 @@ "integrity": "sha512-zeYWrQ9IIe+7J177qFs6eCFfD7WhK2chmdc/lkePrHWazahX+SgLir5VwX3cqx3SsOUuEhRYujhdc5hLcGVBXw==", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "babel-preset-metal": { @@ -12224,9 +13234,9 @@ "integrity": "sha1-55TKuzcQJ9YyNqDwTQLHKPkRcCU=", "dev": true, "requires": { - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-preset-es2015": "6.24.1", - "resolve": "1.4.0" + "babel-plugin-transform-es2015-classes": "^6.2.2", + "babel-preset-es2015": "^6.1.18", + "resolve": "^1.1.7" } } } @@ -12236,7 +13246,7 @@ "resolved": "https://registry.npmjs.org/metal-path-parser/-/metal-path-parser-1.0.3.tgz", "integrity": "sha1-PQisK1bfLTlxfJ1k0eo+4BfsQPc=", "requires": { - "metal": "2.16.5" + "metal": "^2.0.0" } }, "metal-promise": { @@ -12244,7 +13254,7 @@ "resolved": "https://registry.npmjs.org/metal-promise/-/metal-promise-2.0.1.tgz", "integrity": "sha1-KP9DIQ5MaeX/9R2/IB5K4v5vg9U=", "requires": { - "metal": "2.16.5" + "metal": "^2.0.0" } }, "metal-structs": { @@ -12252,7 +13262,7 @@ "resolved": "https://registry.npmjs.org/metal-structs/-/metal-structs-1.0.1.tgz", "integrity": "sha1-VIJy9xjunXKeMHm3Sj8SVBQ9t1s=", "requires": { - "metal": "2.16.5" + "metal": "^2.0.0" } }, "metal-tools-build-rollup": { @@ -12261,16 +13271,16 @@ "integrity": "sha1-Ax0zOIxMpCqpt4RKAZSxrs5s/5I=", "dev": true, "requires": { - "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" + "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" } }, "metal-uri": { @@ -12278,10 +13288,10 @@ "resolved": "https://registry.npmjs.org/metal-uri/-/metal-uri-2.2.6.tgz", "integrity": "sha512-j+hPueDxf5z5eVgtaIOEo1flwEIqNDhrrmiq5Wi3zZ0FEWlqC1g3ZC0I5sqHm1XV54PX0iSG23A66PfaxFg8fg==", "requires": { - "metal": "2.16.5", - "metal-structs": "1.0.1", + "metal": "^2.0.0", + "metal-structs": "^1.0.0", "path-browserify": "0.0.0", - "url": "0.11.0" + "url": "^0.11.0" } }, "metal-useragent": { @@ -12289,7 +13299,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": { @@ -12299,9 +13309,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": { @@ -12324,19 +13334,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "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" + "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" } }, "mime": { @@ -12357,7 +13367,7 @@ "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", "dev": true, "requires": { - "mime-db": "1.29.0" + "mime-db": "~1.29.0" } }, "minimatch": { @@ -12366,7 +13376,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -12429,8 +13439,8 @@ "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", "dev": true, "requires": { - "inherits": "2.0.3", - "minimatch": "0.3.0" + "inherits": "2", + "minimatch": "0.3" } }, "minimatch": { @@ -12439,8 +13449,8 @@ "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", "dev": true, "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" + "lru-cache": "2", + "sigmund": "~1.0.0" } }, "ms": { @@ -12469,11 +13479,11 @@ "integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=", "dev": true, "requires": { - "basic-auth": "1.0.4", - "debug": "2.2.0", - "depd": "1.0.1", - "on-finished": "2.3.0", - "on-headers": "1.0.1" + "basic-auth": "~1.0.3", + "debug": "~2.2.0", + "depd": "~1.0.1", + "on-finished": "~2.3.0", + "on-headers": "~1.0.0" }, "dependencies": { "debug": { @@ -12505,8 +13515,8 @@ "integrity": "sha1-Nd5oBNwZZD5SSfPT473GyM4wHT8=", "dev": true, "requires": { - "readable-stream": "1.1.14", - "stream-counter": "0.2.0" + "readable-stream": "~1.1.9", + "stream-counter": "~0.2.0" }, "dependencies": { "isarray": { @@ -12521,10 +13531,10 @@ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -12587,8 +13597,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": { @@ -12603,9 +13613,9 @@ "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", "dev": true, "requires": { - "ansi-styles": "1.0.0", - "has-color": "0.1.7", - "strip-ansi": "0.1.1" + "ansi-styles": "~1.0.0", + "has-color": "~0.1.0", + "strip-ansi": "~0.1.0" } }, "strip-ansi": { @@ -12628,7 +13638,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1.0.9" + "abbrev": "1" } }, "normalize-package-data": { @@ -12637,10 +13647,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "4.3.6", - "validate-npm-package-license": "3.0.1" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { @@ -12649,7 +13659,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.0.2" + "remove-trailing-separator": "^1.0.1" } }, "normalize-range": { @@ -12688,10 +13698,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.1" + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" }, "dependencies": { "for-own": { @@ -12700,7 +13710,7 @@ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "isobject": { @@ -12717,8 +13727,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "object.pick": { @@ -12727,7 +13737,7 @@ "integrity": "sha1-tTkr7peC2m2ft9avr1OXefEjTCs=", "dev": true, "requires": { - "isobject": "2.1.0" + "isobject": "^2.1.0" } }, "on-finished": { @@ -12751,7 +13761,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -12766,8 +13776,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" }, "dependencies": { "wordwrap": { @@ -12784,12 +13794,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "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" + "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" } }, "orchestrator": { @@ -12798,9 +13808,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": { @@ -12827,9 +13837,9 @@ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1" + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" } }, "parse-filepath": { @@ -12838,9 +13848,9 @@ "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", "dev": true, "requires": { - "is-absolute": "0.2.6", - "map-cache": "0.2.2", - "path-root": "0.1.1" + "is-absolute": "^0.2.3", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" } }, "parse-glob": { @@ -12849,10 +13859,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-json": { @@ -12861,7 +13871,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "parse-passwd": { @@ -12887,7 +13897,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { @@ -12914,7 +13924,7 @@ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "requires": { - "path-root-regex": "0.1.2" + "path-root-regex": "^0.1.0" } }, "path-root-regex": { @@ -12929,9 +13939,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pause": { @@ -12946,7 +13956,7 @@ "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { - "through": "2.3.8" + "through": "~2.3" } }, "pify": { @@ -12967,7 +13977,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pluralize": { @@ -12988,10 +13998,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": { @@ -13000,7 +14010,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } @@ -13075,8 +14085,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": { @@ -13085,7 +14095,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -13094,7 +14104,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "^1.1.5" } } } @@ -13105,7 +14115,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "^1.1.5" } } } @@ -13147,9 +14157,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -13158,8 +14168,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "readable-stream": { @@ -13168,13 +14178,13 @@ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", "dev": true, "requires": { - "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" + "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" } }, "readdirp": { @@ -13184,10 +14194,10 @@ "dev": true, "optional": true, "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.3", - "set-immediate-shim": "1.0.1" + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" } }, "readline2": { @@ -13196,8 +14206,8 @@ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", "mute-stream": "0.0.5" } }, @@ -13207,7 +14217,7 @@ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "resolve": "1.4.0" + "resolve": "^1.1.6" } }, "redent": { @@ -13216,8 +14226,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": { @@ -13238,9 +14248,9 @@ "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", "dev": true, "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0", - "private": "0.1.7" + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" } }, "regex-cache": { @@ -13249,8 +14259,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": { @@ -13265,9 +14275,9 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "1.3.2", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "regjsgen": { @@ -13282,7 +14292,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" }, "dependencies": { "jsesc": { @@ -13317,7 +14327,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "replace-ext": { @@ -13338,8 +14348,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" } }, "requizzle": { @@ -13348,7 +14358,7 @@ "integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=", "dev": true, "requires": { - "underscore": "1.6.0" + "underscore": "~1.6.0" }, "dependencies": { "underscore": { @@ -13365,7 +14375,7 @@ "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", "dev": true, "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, "resolve-dir": { @@ -13374,8 +14384,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": { @@ -13396,8 +14406,8 @@ "integrity": "sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=", "dev": true, "requires": { - "depd": "1.1.1", - "on-headers": "1.0.1" + "depd": "~1.1.0", + "on-headers": "~1.0.1" }, "dependencies": { "depd": { @@ -13414,8 +14424,8 @@ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "dev": true, "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, "right-align": { @@ -13425,7 +14435,7 @@ "dev": true, "optional": true, "requires": { - "align-text": "0.1.4" + "align-text": "^0.1.1" } }, "rimraf": { @@ -13434,7 +14444,7 @@ "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "rndm": { @@ -13449,7 +14459,7 @@ "integrity": "sha1-MEj2SyOIuN2Okz+a1EPws4mrYI8=", "dev": true, "requires": { - "esprima": "2.7.3" + "esprima": "^2.0" }, "dependencies": { "esprima": { @@ -13466,7 +14476,7 @@ "integrity": "sha1-vUmxPb5hInWDdP/SR9inOeghSG8=", "dev": true, "requires": { - "rocambole-token": "1.2.1" + "rocambole-token": "^1.1.0" } }, "rocambole-node-update": { @@ -13475,7 +14485,7 @@ "integrity": "sha1-o//JaLDzvNnPKpM23A234lTIPFo=", "dev": true, "requires": { - "rocambole-token": "1.2.1" + "rocambole-token": "^1.2.1" } }, "rocambole-strip-alert": { @@ -13484,7 +14494,7 @@ "integrity": "sha1-OyVf5vGNYwH4BaFOVwsfHy26hX8=", "dev": true, "requires": { - "rocambole-node-update": "1.0.1" + "rocambole-node-update": "^1.0.1" } }, "rocambole-strip-console": { @@ -13493,7 +14503,7 @@ "integrity": "sha1-K5fj36bhnUUo6+galCMdyeiqygs=", "dev": true, "requires": { - "rocambole-node-update": "1.0.1" + "rocambole-node-update": "^1.0.0" } }, "rocambole-strip-debugger": { @@ -13502,7 +14512,7 @@ "integrity": "sha1-HFUCQgw9bvXiOnC4BUff0dS7y3Y=", "dev": true, "requires": { - "rocambole-node-remove": "1.0.0" + "rocambole-node-remove": "^1.0.0" } }, "rocambole-token": { @@ -13517,7 +14527,7 @@ "integrity": "sha512-2+bq5GQSrocdhr+M92mOQRmF1evtLRzv9NdmEC2wo7BILvTG8irHCtD0q+zg8ikNu63iJicdN5IzyxAXRTFKOQ==", "dev": true, "requires": { - "source-map-support": "0.4.15" + "source-map-support": "^0.4.0" } }, "rollup-plugin-babel": { @@ -13526,10 +14536,10 @@ "integrity": "sha1-FlKBl7D5OKFTb0RoPHqT1XMYL1c=", "dev": true, "requires": { - "babel-core": "6.25.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "object-assign": "4.1.1", - "rollup-pluginutils": "1.5.2" + "babel-core": "6", + "babel-plugin-transform-es2015-classes": "^6.9.0", + "object-assign": "^4.1.0", + "rollup-pluginutils": "^1.5.0" } }, "rollup-plugin-node-resolve": { @@ -13538,9 +14548,9 @@ "integrity": "sha1-y7eDsNFbAnlNWJFTULLw2QK43cg=", "dev": true, "requires": { - "browser-resolve": "1.11.2", - "builtin-modules": "1.1.1", - "resolve": "1.4.0" + "browser-resolve": "^1.11.0", + "builtin-modules": "^1.1.0", + "resolve": "^1.1.6" } }, "rollup-pluginutils": { @@ -13549,8 +14559,8 @@ "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", "dev": true, "requires": { - "estree-walker": "0.2.1", - "minimatch": "3.0.4" + "estree-walker": "^0.2.1", + "minimatch": "^3.0.2" } }, "rollup-stream": { @@ -13559,7 +14569,7 @@ "integrity": "sha512-niUbTM3sqckz1FNebsSiN+koCR7RdgrRZ2HCcR4V2DT9PSs53tB4z1xzdTGxrX6bo3QT00R2sQA5n1jr/to69Q==", "dev": true, "requires": { - "rollup": "0.45.2" + "rollup": "^0.45.1" } }, "run-async": { @@ -13568,7 +14578,7 @@ "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", "dev": true, "requires": { - "once": "1.4.0" + "once": "^1.3.0" } }, "run-sequence": { @@ -13577,8 +14587,8 @@ "integrity": "sha1-UJWgvr6YczsBQL0I3YDsAw3azes=", "dev": true, "requires": { - "chalk": "1.1.3", - "gulp-util": "3.0.8" + "chalk": "*", + "gulp-util": "*" } }, "rx-lite": { @@ -13605,9 +14615,9 @@ "integrity": "sha1-cw/6Ikm98YMz7/5FsoYXPJxa0Lg=", "dev": true, "requires": { - "htmlparser2": "3.9.2", + "htmlparser2": "^3.9.0", "regexp-quote": "0.0.0", - "xtend": "4.0.1" + "xtend": "^4.0.0" } }, "semver": { @@ -13622,18 +14632,18 @@ "integrity": "sha1-dl52B8gFVFK7pvCwUllTUJhgNt4=", "dev": true, "requires": { - "debug": "2.2.0", - "depd": "1.1.1", - "destroy": "1.0.4", - "escape-html": "1.0.3", - "etag": "1.7.0", + "debug": "~2.2.0", + "depd": "~1.1.0", + "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": { @@ -13677,10 +14687,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": { @@ -13697,13 +14707,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.16", - "parseurl": "1.3.1" + "debug": "~2.2.0", + "escape-html": "~1.0.3", + "http-errors": "~1.3.1", + "mime-types": "~2.1.9", + "parseurl": "~1.3.1" }, "dependencies": { "debug": { @@ -13729,8 +14739,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" } }, @@ -13747,9 +14757,9 @@ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true, "requires": { - "glob": "7.1.2", - "interpret": "1.0.3", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "sigmund": { @@ -13773,7 +14783,7 @@ "formatio": "1.1.1", "lolex": "1.3.2", "samsam": "1.1.2", - "util": "0.10.3" + "util": ">=0.10.3 <1" } }, "slash": { @@ -13800,10 +14810,10 @@ "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", "dev": true, "requires": { - "atob": "1.1.3", - "resolve-url": "0.2.1", - "source-map-url": "0.3.0", - "urix": "0.1.0" + "atob": "~1.1.0", + "resolve-url": "~0.2.1", + "source-map-url": "~0.3.0", + "urix": "~0.1.0" } }, "source-map-support": { @@ -13812,7 +14822,7 @@ "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "^0.5.6" } }, "source-map-url": { @@ -13833,7 +14843,7 @@ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-license-ids": "^1.0.2" } }, "spdx-expression-parse": { @@ -13854,7 +14864,7 @@ "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { - "through": "2.3.8" + "through": "2" } }, "sprintf-js": { @@ -13875,7 +14885,7 @@ "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { - "duplexer": "0.1.1" + "duplexer": "~0.1.1" } }, "stream-consume": { @@ -13890,7 +14900,7 @@ "integrity": "sha1-3tJmVWMZyLDiIoErnPOyb6fZR94=", "dev": true, "requires": { - "readable-stream": "1.1.14" + "readable-stream": "~1.1.8" }, "dependencies": { "isarray": { @@ -13905,10 +14915,10 @@ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -13925,9 +14935,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -13936,7 +14946,7 @@ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -13945,7 +14955,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -13954,8 +14964,8 @@ "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", "dev": true, "requires": { - "first-chunk-stream": "1.0.0", - "is-utf8": "0.2.1" + "first-chunk-stream": "^1.0.0", + "is-utf8": "^0.2.0" } }, "strip-bom-string": { @@ -13970,10 +14980,10 @@ "integrity": "sha1-aYJBmGdp3O9RPcbHymKbBryfIXs=", "dev": true, "requires": { - "rocambole": "0.5.1", - "rocambole-strip-alert": "1.0.0", - "rocambole-strip-console": "1.0.0", - "rocambole-strip-debugger": "1.0.0" + "rocambole": "^0.5.0", + "rocambole-strip-alert": "^1.0.0", + "rocambole-strip-console": "^1.0.0", + "rocambole-strip-debugger": "^1.0.0" } }, "strip-indent": { @@ -13982,7 +14992,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "4.0.1" + "get-stdin": "^4.0.1" } }, "strip-json-comments": { @@ -14003,12 +15013,12 @@ "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "dev": true, "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", "slice-ansi": "0.0.4", - "string-width": "2.1.1" + "string-width": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -14029,8 +15039,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": { @@ -14039,7 +15049,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -14068,8 +15078,8 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "2.3.3", - "xtend": "4.0.1" + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" } }, "tildify": { @@ -14078,7 +15088,7 @@ "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.0" } }, "time-stamp": { @@ -14093,8 +15103,8 @@ "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", "dev": true, "requires": { - "es5-ext": "0.10.24", - "next-tick": "1.0.0" + "es5-ext": "~0.10.14", + "next-tick": "1" } }, "tiny-lr": { @@ -14103,12 +15113,12 @@ "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "body-parser": { @@ -14118,15 +15128,15 @@ "dev": true, "requires": { "bytes": "2.2.0", - "content-type": "1.0.2", - "debug": "2.2.0", - "depd": "1.1.1", - "http-errors": "1.3.1", + "content-type": "~1.0.1", + "debug": "~2.2.0", + "depd": "~1.1.0", + "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.7", - "type-is": "1.6.15" + "raw-body": "~2.1.5", + "type-is": "~1.6.10" }, "dependencies": { "qs": { @@ -14184,7 +15194,7 @@ "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.1" } }, "to-fast-properties": { @@ -14236,7 +15246,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "type-detect": { @@ -14252,7 +15262,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.16" + "mime-types": "~2.1.15" } }, "typedarray": { @@ -14273,10 +15283,10 @@ "integrity": "sha1-wrDlpzOdeG3d03R7FT5/ZDPx/iA=", "dev": true, "requires": { - "babylon": "6.17.4", - "commander": "2.11.0", - "typhonjs-escomplex-module": "0.0.12", - "typhonjs-escomplex-project": "0.0.12" + "babylon": "^6.0.0", + "commander": "^2.0.0", + "typhonjs-escomplex-module": "^0.0.12", + "typhonjs-escomplex-project": "^0.0.12" } }, "typhonjs-escomplex-commons": { @@ -14291,11 +15301,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.1", - "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.0", + "typhonjs-escomplex-commons": "^0.0.16", + "typhonjs-plugin-manager": "^0.0.3" } }, "typhonjs-escomplex-project": { @@ -14304,10 +15314,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": { @@ -14323,9 +15333,9 @@ "dev": true, "optional": true, "requires": { - "source-map": "0.5.6", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" } }, "uglify-to-browserify": { @@ -14341,7 +15351,7 @@ "integrity": "sha1-Otbzg2jG1MjHXsF2I/t5qh0HHYE=", "dev": true, "requires": { - "random-bytes": "1.0.0" + "random-bytes": "~1.0.0" } }, "unc-path-regex": { @@ -14441,7 +15451,7 @@ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { - "user-home": "1.1.1" + "user-home": "^1.1.1" } }, "validate-npm-package-license": { @@ -14450,8 +15460,8 @@ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" } }, "vary": { @@ -14472,8 +15482,8 @@ "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", "dev": true, "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } }, @@ -14483,8 +15493,8 @@ "integrity": "sha1-ygZ+oIQx1QdyKx3lCD9gJhbrwjQ=", "dev": true, "requires": { - "bl": "0.9.5", - "through2": "0.6.5" + "bl": "^0.9.1", + "through2": "^0.6.1" }, "dependencies": { "isarray": { @@ -14499,10 +15509,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -14517,8 +15527,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } } } @@ -14529,14 +15539,14 @@ "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", "dev": true, "requires": { - "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" + "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" }, "dependencies": { "clone": { @@ -14551,7 +15561,7 @@ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", "dev": true, "requires": { - "natives": "1.1.0" + "natives": "^1.1.0" } }, "isarray": { @@ -14566,10 +15576,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -14584,8 +15594,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } }, "vinyl": { @@ -14594,8 +15604,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" } } } @@ -14606,8 +15616,8 @@ "integrity": "sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas=", "dev": true, "requires": { - "through2": "0.6.5", - "vinyl": "0.4.6" + "through2": "^0.6.1", + "vinyl": "^0.4.3" }, "dependencies": { "clone": { @@ -14628,10 +15638,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -14646,8 +15656,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } }, "vinyl": { @@ -14656,8 +15666,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" } } } @@ -14668,7 +15678,7 @@ "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "^0.5.1" } }, "websocket-driver": { @@ -14677,7 +15687,7 @@ "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", "dev": true, "requires": { - "websocket-extensions": "0.1.1" + "websocket-extensions": ">=0.1.1" } }, "websocket-extensions": { @@ -14692,7 +15702,7 @@ "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "window-size": { @@ -14720,7 +15730,7 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "xmlcreate": { @@ -14742,9 +15752,9 @@ "dev": true, "optional": true, "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", "window-size": "0.1.0" } }