diff --git a/bin/wmscapabilities b/bin/wmscapabilities index a7d4576..566b6df 100755 --- a/bin/wmscapabilities +++ b/bin/wmscapabilities @@ -2,7 +2,7 @@ var xmldom = require('xmldom'); var DOMParser = global.DOMParser = xmldom.DOMParser; -var WMSCapabilites = require('../'); +var WMSCapabilites = require('../dist/wms-capabilities.min.js'); var fs = require('fs'); var path = require('path'); diff --git a/dist/wms-capabilities.js b/dist/wms-capabilities.js index 2fee519..407266d 100644 --- a/dist/wms-capabilities.js +++ b/dist/wms-capabilities.js @@ -1,9 +1,9 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.WMSCapabilities=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o} objectStack Object stack + * @return {Object} + */ +WMS._readScaleHint = function(node, objectStack) { + var min = parseFloat(node.getAttribute('min')); + var max = parseFloat(node.getAttribute('max')); + + return { + min: min, + max: max + }; +}; + + /** * @private * @param {Node} node Node. @@ -749,6 +766,7 @@ WMS.LAYER_PARSERS = XMLParser.makeParsersNS( 'Style': XMLParser.makeObjectPropertyPusher(WMS._readStyle), 'MinScaleDenominator': makePropertySetter(XSD.readDecimal), 'MaxScaleDenominator': makePropertySetter(XSD.readDecimal), + 'ScaleHint': makePropertySetter(WMS._readScaleHint), 'Layer': XMLParser.makeObjectPropertyPusher(WMS._readLayer) }); @@ -879,7 +897,7 @@ WMS.KEYWORDLIST_PARSERS = XMLParser.makeParsersNS( module.exports = WMS; -},{"./node_types":2,"./utils/isdef":3,"./utils/setifundefined":4,"./xlink":7,"./xml_parser":8,"./xsd":9}],7:[function(_dereq_,module,exports){ +},{"./node_types":2,"./utils/isdef":3,"./utils/setifundefined":4,"./xlink":7,"./xml_parser":8,"./xsd":9}],7:[function(require,module,exports){ "use strict"; /** @@ -899,12 +917,12 @@ module.exports = { } }; -},{}],8:[function(_dereq_,module,exports){ +},{}],8:[function(require,module,exports){ "use strict"; -var isDef = _dereq_('./utils/isdef'); -var setIfUndefined = _dereq_('./utils/setifundefined'); -var nodeTypes = _dereq_('./node_types'); +var isDef = require('./utils/isdef'); +var setIfUndefined = require('./utils/setifundefined'); +var nodeTypes = require('./node_types'); /** * XML DOM parser @@ -1133,12 +1151,12 @@ XMLParser.pushParseAndPop = function(object, parsersNS, node, objectStack, bind) module.exports = XMLParser; -},{"./node_types":2,"./utils/isdef":3,"./utils/setifundefined":4}],9:[function(_dereq_,module,exports){ +},{"./node_types":2,"./utils/isdef":3,"./utils/setifundefined":4}],9:[function(require,module,exports){ "use strict"; -var isDef = _dereq_('./utils/isdef'); -var string = _dereq_('./utils/string'); -var XMLParser = _dereq_('./xml_parser'); +var isDef = require('./utils/isdef'); +var string = require('./utils/string'); +var XMLParser = require('./xml_parser'); var XSD = {}; @@ -1315,6 +1333,5 @@ XSD.writeStringTextNode = function(node, string) { module.exports = XSD; -},{"./utils/isdef":3,"./utils/string":5,"./xml_parser":8}]},{},[1]) -(1) +},{"./utils/isdef":3,"./utils/string":5,"./xml_parser":8}]},{},[1])(1) }); \ No newline at end of file diff --git a/dist/wms-capabilities.min.js b/dist/wms-capabilities.min.js index 8bb65a7..cb09a6f 100644 --- a/dist/wms-capabilities.min.js +++ b/dist/wms-capabilities.min.js @@ -1 +1,19 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;"undefined"!=typeof window?r=window:"undefined"!=typeof global?r=global:"undefined"!=typeof self&&(r=self),r.WMSCapabilities=e()}}(function(){return function e(r,t,n){function a(o,u){if(!t[o]){if(!r[o]){var d="function"==typeof require&&require;if(!u&&d)return d(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var s=t[o]={exports:{}};r[o][0].call(s.exports,function(e){var t=r[o][1][e];return a(t?t:e)},s,s.exports,e,r,t,n)}return t[o].exports}for(var i="function"==typeof require&&require,o=0;og;g++){var E=P[g],_=i[E];if(a(_)){var R=o(d,E,[]);R=R.concat(_),d[E]=R}}for(var m=["EX_GeographicBoundingBox","BoundingBox","Dimension","Attribution","MinScaleDenominator","MaxScaleDenominator"],g=0,f=m.length;f>g;g++){var E=m[g],R=d[E];if(!a(R)){var _=i[E];d[E]=_}}return d},t._readDimension=function(e){var r={name:e.getAttribute("name"),units:e.getAttribute("units"),unitSymbol:e.getAttribute("unitSymbol"),"default":e.getAttribute("default"),multipleValues:u.readBooleanString(e.getAttribute("multipleValues")),nearestValue:u.readBooleanString(e.getAttribute("nearestValue")),current:u.readBooleanString(e.getAttribute("current")),values:u.readString(e)};return r},t._readFormatOnlineresource=function(e,r){return n.pushParseAndPop({},t.FORMAT_ONLINERESOURCE_PARSERS,e,r)},t._readRequest=function(e,r){return n.pushParseAndPop({},t.REQUEST_PARSERS,e,r)},t._readDCPType=function(e,r){return n.pushParseAndPop({},t.DCPTYPE_PARSERS,e,r)},t._readHTTP=function(e,r){return n.pushParseAndPop({},t.HTTP_PARSERS,e,r)},t._readOperationType=function(e,r){return n.pushParseAndPop({},t.OPERATIONTYPE_PARSERS,e,r)},t._readSizedFormatOnlineresource=function(e,r){var n=t._readFormatOnlineresource(e,r);if(a(n)){var i=u.readNonNegativeIntegerString,o=[i(e.getAttribute("width")),i(e.getAttribute("height"))];return n.size=o,n}return void 0},t._readAuthorityURL=function(e,r){var n=t._readFormatOnlineresource(e,r);return a(n)?(n.name=e.getAttribute("name"),n):void 0},t._readMetadataURL=function(e,r){var n=t._readFormatOnlineresource(e,r);return a(n)?(n.type=e.getAttribute("type"),n):void 0},t._readStyle=function(e,r){return n.pushParseAndPop({},t.STYLE_PARSERS,e,r)},t._readKeywordList=function(e,r){return n.pushParseAndPop([],t.KEYWORDLIST_PARSERS,e,r)},t.NAMESPACE_URIS=[null,"http://www.opengis.net/wms"],t.PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Service:s(t._readService),Capability:s(t._readCapability)}),t.CAPABILITY_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Request:s(t._readRequest),Exception:s(t._readException),Layer:s(t._readCapabilityLayer)}),t.SERVICE_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Name:s(u.readString),Title:s(u.readString),Abstract:s(u.readString),KeywordList:s(t._readKeywordList),OnlineResource:s(d.readHref),ContactInformation:s(t._readContactInformation),Fees:s(u.readString),AccessConstraints:s(u.readString),LayerLimit:s(u.readNonNegativeInteger),MaxWidth:s(u.readNonNegativeInteger),MaxHeight:s(u.readNonNegativeInteger)}),t.CONTACT_INFORMATION_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{ContactPersonPrimary:s(t._readContactPersonPrimary),ContactPosition:s(u.readString),ContactAddress:s(t._readContactAddress),ContactVoiceTelephone:s(u.readString),ContactFacsimileTelephone:s(u.readString),ContactElectronicMailAddress:s(u.readString)}),t.CONTACT_PERSON_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{ContactPerson:s(u.readString),ContactOrganization:s(u.readString)}),t.CONTACT_ADDRESS_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{AddressType:s(u.readString),Address:s(u.readString),City:s(u.readString),StateOrProvince:s(u.readString),PostCode:s(u.readString),Country:s(u.readString)}),t.EXCEPTION_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Format:n.makeArrayPusher(u.readString)}),t.LAYER_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Name:s(u.readString),Title:s(u.readString),Abstract:s(u.readString),KeywordList:s(t._readKeywordList),CRS:n.makeObjectPropertyPusher(u.readString),SRS:n.makeObjectPropertyPusher(u.readString),EX_GeographicBoundingBox:s(t._readEXGeographicBoundingBox),LatLonBoundingBox:s(t._readLatLonBoundingBox),BoundingBox:n.makeObjectPropertyPusher(t._readBoundingBox),Dimension:n.makeObjectPropertyPusher(t._readDimension),Attribution:s(t._readAttribution),AuthorityURL:n.makeObjectPropertyPusher(t._readAuthorityURL),Identifier:n.makeObjectPropertyPusher(u.readString),MetadataURL:n.makeObjectPropertyPusher(t._readMetadataURL),DataURL:n.makeObjectPropertyPusher(t._readFormatOnlineresource),FeatureListURL:n.makeObjectPropertyPusher(t._readFormatOnlineresource),Style:n.makeObjectPropertyPusher(t._readStyle),MinScaleDenominator:s(u.readDecimal),MaxScaleDenominator:s(u.readDecimal),Layer:n.makeObjectPropertyPusher(t._readLayer)}),t.ATTRIBUTION_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Title:s(u.readString),OnlineResource:s(d.readHref),LogoURL:s(t._readSizedFormatOnlineresource)}),t.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{westBoundLongitude:s(u.readDecimal),eastBoundLongitude:s(u.readDecimal),southBoundLatitude:s(u.readDecimal),northBoundLatitude:s(u.readDecimal)}),t.REQUEST_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{GetCapabilities:s(t._readOperationType),GetMap:s(t._readOperationType),GetFeatureInfo:s(t._readOperationType)}),t.OPERATIONTYPE_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Format:n.makeObjectPropertyPusher(u.readString),DCPType:n.makeObjectPropertyPusher(t._readDCPType)}),t.DCPTYPE_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{HTTP:s(t._readHTTP)}),t.HTTP_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Get:s(t._readFormatOnlineresource),Post:s(t._readFormatOnlineresource)}),t.STYLE_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Name:s(u.readString),Title:s(u.readString),Abstract:s(u.readString),LegendURL:n.makeObjectPropertyPusher(t._readSizedFormatOnlineresource),StyleSheetURL:s(t._readFormatOnlineresource),StyleURL:s(t._readFormatOnlineresource)}),t.FORMAT_ONLINERESOURCE_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Format:s(u.readString),OnlineResource:s(d.readHref)}),t.KEYWORDLIST_PARSERS=n.makeParsersNS(t.NAMESPACE_URIS,{Keyword:n.makeArrayPusher(u.readString)}),r.exports=t},{"./node_types":2,"./utils/isdef":3,"./utils/setifundefined":4,"./xlink":7,"./xml_parser":8,"./xsd":9}],7:[function(e,r){"use strict";var t="http://www.w3.org/1999/xlink";r.exports={readHref:function(e){return e.getAttributeNS(t,"href")}}},{}],8:[function(e,r){"use strict";function t(){this._parser=new DOMParser}var n=e("./utils/isdef"),a=e("./utils/setifundefined"),i=e("./node_types");t.prototype.toDocument=function(e){return this._parser.parseFromString(e,"application/xml")},t.getAllTextContent=function(e,r){return t.getAllTextContent_(e,r,[]).join("")},t.getAllTextContent_=function(e,r,n){if(e.nodeType===i.CDATA_SECTION||e.nodeType===i.TEXT)n.push(r?String(e.nodeValue).replace(/(\r\n|\r|\n)/g,""):e.nodeValue);else{var a;for(a=e.firstChild;a;a=a.nextSibling)t.getAllTextContent_(a,r,n)}return n},t.parseNode=function(e,r,a,i){for(var o=t.firstElementChild(r);o;o=t.nextElementSibling(o)){var u=o.namespaceURI||null,d=e[u];if(n(d)){var s=d[o.localName];n(s)&&s.call(i,o,a)}}},t.firstElementChild=function(e){for(var r=e.firstElementChild||e.firstChild;r&&r.nodeType!==i.ELEMENT;)r=r.nextSibling;return r},t.nextElementSibling=function(e){for(var r=e.nextElementSibling||e.nextSibling;r&&r.nodeType!==i.ELEMENT;)r=r.nextSibling;return r},t.makeParsersNS=function(e,r,n){return t.makeStructureNS(e,r,n)},t.makeStructureNS=function(e,r,t){var a,i,o=n(t)?t:{};for(a=0,i=e.length;i>a;++a)o[e[a]]=r;return o},t.makeObjectPropertySetter=function(e,r,t){return function(a,i){var o=e.call(n(t)?t:this,a,i);if(n(o)){var u=i[i.length-1],d=n(r)?r:a.localName;u[d]=o}}},t.makeObjectPropertyPusher=function(e,r,t){return function(i,o){var u=e.call(n(t)?t:this,i,o);if(n(u)){var d=o[o.length-1],s=n(r)?r:i.localName,S=a(d,s,[]);S.push(u)}}},t.makeArrayPusher=function(e,r){return function(t,a){var i=e.call(n(r)?r:this,t,a);if(n(i)){var o=a[a.length-1];o.push(i)}}},t.pushParseAndPop=function(e,r,n,a,i){return a.push(e),t.parseNode(r,n,a,i),a.pop()},r.exports=t},{"./node_types":2,"./utils/isdef":3,"./utils/setifundefined":4}],9:[function(e,r){"use strict";var t=e("./utils/isdef"),n=e("./utils/string"),a=e("./xml_parser"),i={};i.NAMESPACE_URI="http://www.w3.org/2001/XMLSchema",i.readBoolean=function(e){var r=a.getAllTextContent(e,!1);return i.readBooleanString(r)},i.readBooleanString=function(e){var r=/^\s*(true|1)|(false|0)\s*$/.exec(e);return r?t(r[1])||!1:void 0},i.readDateTime=function(e){var r=a.getAllTextContent(e,!1),n=/^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(?:([+\-])(\d{2})(?::(\d{2}))?))\s*$/,i=n.exec(r);if(i){var o=parseInt(i[1],10),u=parseInt(i[2],10)-1,d=parseInt(i[3],10),s=parseInt(i[4],10),S=parseInt(i[5],10),c=parseInt(i[6],10),l=Date.UTC(o,u,d,s,S,c)/1e3;if("Z"!=i[7]){var p="-"==i[8]?-1:1;l+=60*p*parseInt(i[9],10),t(i[10])&&(l+=60*p*60*parseInt(i[10],10))}return l}return void 0},i.readDecimal=function(e){var r=a.getAllTextContent(e,!1);return i.readDecimalString(r)},i.readDecimalString=function(e){var r=/^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*$/i.exec(e);return r?parseFloat(r[1]):void 0},i.readNonNegativeInteger=function(e){var r=a.getAllTextContent(e,!1);return i.readNonNegativeIntegerString(r)},i.readNonNegativeIntegerString=function(e){var r=/^\s*(\d+)\s*$/.exec(e);return r?parseInt(r[1],10):void 0},i.readString=function(e){var r=a.getAllTextContent(e,!1);return n.trim(r)},i.writeBooleanTextNode=function(e,r){i.writeStringTextNode(e,r?"1":"0")},i.writeDateTimeTextNode=function(e,r){var t=new Date(1e3*r),n=t.getUTCFullYear()+"-"+n.padNumber(t.getUTCMonth()+1,2)+"-"+n.padNumber(t.getUTCDate(),2)+"T"+n.padNumber(t.getUTCHours(),2)+":"+n.padNumber(t.getUTCMinutes(),2)+":"+n.padNumber(t.getUTCSeconds(),2)+"Z";e.appendChild(a.DOCUMENT.createTextNode(n))},i.writeDecimalTextNode=function(e,r){var t=r.toPrecision();e.appendChild(a.DOCUMENT.createTextNode(t))},i.writeNonNegativeIntegerTextNode=function(e,r){var t=r.toString();e.appendChild(a.DOCUMENT.createTextNode(t))},i.writeStringTextNode=function(e,r){e.appendChild(a.DOCUMENT.createTextNode(r))},r.exports=i},{"./utils/isdef":3,"./utils/string":5,"./xml_parser":8}]},{},[1])(1)}); \ No newline at end of file +(function(r){"object"===typeof exports&&"undefined"!==typeof module?module.exports=r():"function"===typeof define&&define.Na?define([],r):("undefined"!==typeof window?window:"undefined"!==typeof global?global:"undefined"!==typeof self?self:this).WMSCapabilities=r()})(function(){return function g(h,a,e){function f(c,m){if(!a[c]){if(!h[c]){var b="function"==typeof require&&require;if(!m&&b)return b(c,!0);if(l)return l(c,!0);b=Error("Cannot find module '"+c+"'");throw b.code="MODULE_NOT_FOUND",b;}b= +a[c]={exports:{}};h[c][0].call(b.exports,function(a){var b=h[c][1][a];return f(b?b:a)},b,b.exports,g,h,a,e)}return a[c].exports}for(var l="function"==typeof require&&require,c=0;c + + + + + + + tags: + - desktop + - mobile + - text + - input +*/ +.topcoat-select { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + appearance: button; + text-indent: 0.01px; + text-overflow: ''; + padding: 0.7rem 1.3rem 0.7rem 1rem; + font-size: 16px; + font-weight: 400; + height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0, 0, 0, 0.69); + border-radius: 6px; + background-color: #585a5a; + box-shadow: inset 0 1px #737373; + border: 1px solid #323434; + background-image: url('../img/dropdown.svg'); + background-repeat: no-repeat; + background-position: center right; +} +.topcoat-select:hover { + background-color: #616465; +} +.topcoat-select:active { + background-color: #3e4041; + box-shadow: inset 0 1px rgba(0, 0, 0, 0.05); +} +.topcoat-select:focus { + border: 1px solid #0037ff; + box-shadow: 0 0 0 2px #6fb4f1; + outline: 0; +} diff --git a/example/js/app.js b/example/js/app.js index ca4c08d..ed0b1fa 100755 --- a/example/js/app.js +++ b/example/js/app.js @@ -1,6 +1,6 @@ var jsonFormat = global.jsonFormat = require('./json-format'); var xmlFormat = global.xmlFormat = require('./xml-format'); -var WMSCapabilities = global.WMSCapabilities || require('../../index'); +var WMSCapabilities = global.WMSCapabilities || require('../../dist/wms-capabilities.min'); var Spinner = require('spin.js'); var reqwest = global.reqwest = require('reqwest'); diff --git a/example/js/bundle.js b/example/js/bundle.js index 3fef322..17e642e 100644 --- a/example/js/bundle.js +++ b/example/js/bundle.js @@ -1,8 +1,32 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o} obj The object to which to add the key-value pair. - * @param {String} key The key to add. - * @param {V} value The value to add if the key wasn't present. - * @return {V} The value of the entry at the end of the function. - * @template K,V - */ -module.exports = function(obj, key, value) { - return key in obj ? obj[key] : (obj[key] = value); -}; - -},{}],"/Users/w8r/Projects/wms-capabilities/src/utils/string.js":[function(require,module,exports){ -"use strict"; - -var isDef = require('./isdef'); - -/** - * Make sure we trim BOM and NBSP - * @type {RegExp} - */ -var TRIM_RE = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; - -/** - * Repeats a string n times. - * @param {String} string The string to repeat. - * @param {Number} length The number of times to repeat. - * @return {String} A string containing {@code length} repetitions of - * {@code string}. - */ -function repeat(string, length) { - return new Array(length + 1).join(string); -} - -module.exports = { - - /** - * @param {String} str - * @return {String} - */ - trim: function(str) { - return str.replace(TRIM_RE, ''); - }, - - /** - * Pads number to given length and optionally rounds it to a given precision. - * For example: - *
padNumber(1.25, 2, 3) -> '01.250'
-   * padNumber(1.25, 2) -> '01.25'
-   * padNumber(1.25, 2, 1) -> '01.3'
-   * padNumber(1.25, 0) -> '1.25'
- * - * @param {Number} num The number to pad. - * @param {Number} length The desired length. - * @param {Number=} opt_precision The desired precision. - * @return {String} {@code num} as a string with the given options. - */ - padNumber: function(num, length, opt_precision) { - var s = isDef(opt_precision) ? num.toFixed(opt_precision) : String(num); - var index = s.indexOf('.'); - if (index == -1) { - index = s.length; - } - return repeat('0', Math.max(0, length - index)) + s; - } - -}; - -},{"./isdef":"/Users/w8r/Projects/wms-capabilities/src/utils/isdef.js"}],"/Users/w8r/Projects/wms-capabilities/src/wms.js":[function(require,module,exports){ -"use strict"; - -var XMLParser = require('./xml_parser'); -var isDef = require('./utils/isdef'); -var nodeTypes = require('./node_types'); -var setIfUndefined = require('./utils/setifundefined'); -var XSD = require('./xsd'); -var XLink = require('./xlink'); - -/** - * WMS Capabilities parser - * - * @param {String=} xmlString - * @constructor - */ -function WMS(xmlString) { - - /** - * @type {String} - */ - this.version = undefined; - - /** - * @type {XMLParser} - */ - this._parser = new XMLParser(); - - /** - * @type {String=} - */ - this._data = xmlString; -}; - -/** - * Shortcut - * @type {Function} - */ -var makePropertySetter = XMLParser.makeObjectPropertySetter; - -/** - * @param {String} xmlString - * @return {WMS} - */ -WMS.prototype.data = function(xmlString) { - this._data = xmlString; - return this; -}; - -/** - * @param {String=} xmlString - * @return {Object} - */ -WMS.prototype.toJSON = function(xmlString) { - xmlString = xmlString || this._data; - return this.parse(xmlString); -}; - -/** - * @return {String} xml - */ -WMS.prototype.parse = function(xmlString) { - return this._readFromDocument(this._parser.toDocument(xmlString)); -}; - -/** - * @param {Document} doc - * @return {Object} - */ -WMS.prototype._readFromDocument = function(doc) { - for (var node = doc.firstChild; node; node = node.nextSibling) { - if (node.nodeType == nodeTypes.ELEMENT) { - return this.readFromNode(node); - } - } - return null; -}; - -/** - * @param {DOMNode} node - * @return {Object} - */ -WMS.prototype.readFromNode = function(node) { - this.version = node.getAttribute('version'); - var wmsCapabilityObject = XMLParser.pushParseAndPop({ - 'version': this.version - }, WMS.PARSERS, node, []); - - return wmsCapabilityObject || null; -}; - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Attribution object. - */ -WMS._readAttribution = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.ATTRIBUTION_PARSERS, node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object} Bounding box object. - */ -WMS._readBoundingBox = function(node, objectStack) { - var readDecimalString = XSD.readDecimalString; - var extent = [ - readDecimalString(node.getAttribute('minx')), - readDecimalString(node.getAttribute('miny')), - readDecimalString(node.getAttribute('maxx')), - readDecimalString(node.getAttribute('maxy')) - ]; - - var resolutions = [ - readDecimalString(node.getAttribute('resx')), - readDecimalString(node.getAttribute('resy')) - ]; - - return { - 'crs': node.getAttribute('CRS') || node.getAttribute('SRS'), - 'extent': extent, - 'res': resolutions - }; -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {ol.Extent|undefined} Bounding box object. - */ -WMS._readEXGeographicBoundingBox = function(node, objectStack) { - var geographicBoundingBox = XMLParser.pushParseAndPop({}, - WMS.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS, - node, objectStack); - if (!isDef(geographicBoundingBox)) { - return undefined; - } - - var westBoundLongitude = /** @type {number|undefined} */ - (geographicBoundingBox['westBoundLongitude']); - var southBoundLatitude = /** @type {number|undefined} */ - (geographicBoundingBox['southBoundLatitude']); - var eastBoundLongitude = /** @type {number|undefined} */ - (geographicBoundingBox['eastBoundLongitude']); - var northBoundLatitude = /** @type {number|undefined} */ - (geographicBoundingBox['northBoundLatitude']); - - if (!isDef(westBoundLongitude) || !isDef(southBoundLatitude) || - !isDef(eastBoundLongitude) || !isDef(northBoundLatitude)) { - return undefined; - } - - return [ - westBoundLongitude, southBoundLatitude, - eastBoundLongitude, northBoundLatitude - ]; -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Object|undefined} Capability object. - */ -WMS._readCapability = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.CAPABILITY_PARSERS, node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Object|undefined} Service object. - */ -WMS._readService = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.SERVICE_PARSERS, node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Object|undefined} Contact information object. - */ -WMS._readContactInformation = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.CONTACT_INFORMATION_PARSERS, - node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Object|undefined} Contact person object. - */ -WMS._readContactPersonPrimary = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.CONTACT_PERSON_PARSERS, - node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Object|undefined} Contact address object. - */ -WMS._readContactAddress = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.CONTACT_ADDRESS_PARSERS, - node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Array.|undefined} Format array. - */ -WMS._readException = function(node, objectStack) { - return XMLParser.pushParseAndPop( - [], WMS.EXCEPTION_PARSERS, node, objectStack); -}; - - -/** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @private - * @return {Object|undefined} Layer object. - */ -WMS._readCapabilityLayer = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.LAYER_PARSERS, node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Layer object. - */ -WMS._readLayer = function(node, objectStack) { - var parentLayerObject = /** @type {Object.} */ - (objectStack[objectStack.length - 1]); - - var layerObject = /** @type {Object.} */ - (XMLParser.pushParseAndPop({}, WMS.LAYER_PARSERS, - node, objectStack)); - - if (!isDef(layerObject)) { - return undefined; - } - - var queryable = XSD.readBooleanString(node.getAttribute('queryable')); - if (!isDef(queryable)) { - queryable = parentLayerObject['queryable']; - } - layerObject['queryable'] = isDef(queryable) ? queryable : false; - - var cascaded = XSD.readNonNegativeIntegerString(node.getAttribute('cascaded')); - if (!isDef(cascaded)) { - cascaded = parentLayerObject['cascaded']; - } - layerObject['cascaded'] = cascaded; - - var opaque = XSD.readBooleanString(node.getAttribute('opaque')); - if (!isDef(opaque)) { - opaque = parentLayerObject['opaque']; - } - layerObject['opaque'] = isDef(opaque) ? opaque : false; - - var noSubsets = XSD.readBooleanString(node.getAttribute('noSubsets')); - if (!isDef(noSubsets)) { - noSubsets = parentLayerObject['noSubsets']; - } - layerObject['noSubsets'] = isDef(noSubsets) ? noSubsets : false; - - var fixedWidth = XSD.readDecimalString(node.getAttribute('fixedWidth')); - if (!isDef(fixedWidth)) { - fixedWidth = parentLayerObject['fixedWidth']; - } - layerObject['fixedWidth'] = fixedWidth; - - var fixedHeight = XSD.readDecimalString(node.getAttribute('fixedHeight')); - if (!isDef(fixedHeight)) { - fixedHeight = parentLayerObject['fixedHeight']; - } - layerObject['fixedHeight'] = fixedHeight; - - // See 7.2.4.8 - var addKeys = ['Style', 'CRS', 'AuthorityURL']; - for (var i = 0, len = addKeys.length; i < len; i++) { - var key = addKeys[i]; - var parentValue = parentLayerObject[key]; - if (isDef(parentValue)) { - var childValue = setIfUndefined(layerObject, key, []); - childValue = childValue.concat(parentValue); - layerObject[key] = childValue; - } - } - - var replaceKeys = ['EX_GeographicBoundingBox', 'BoundingBox', 'Dimension', - 'Attribution', 'MinScaleDenominator', 'MaxScaleDenominator' - ]; - for (var i = 0, len = replaceKeys.length; i < len; i++) { - var key = replaceKeys[i]; - var childValue = layerObject[key]; - if (!isDef(childValue)) { - var parentValue = parentLayerObject[key]; - layerObject[key] = parentValue; - } - } - - return layerObject; -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object} Dimension object. - */ -WMS._readDimension = function(node, objectStack) { - var dimensionObject = { - 'name': node.getAttribute('name'), - 'units': node.getAttribute('units'), - 'unitSymbol': node.getAttribute('unitSymbol'), - 'default': node.getAttribute('default'), - 'multipleValues': XSD.readBooleanString(node.getAttribute('multipleValues')), - 'nearestValue': XSD.readBooleanString(node.getAttribute('nearestValue')), - 'current': XSD.readBooleanString(node.getAttribute('current')), - 'values': XSD.readString(node) - }; - return dimensionObject; -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Online resource object. - */ -WMS._readFormatOnlineresource = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.FORMAT_ONLINERESOURCE_PARSERS, - node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Request object. - */ -WMS._readRequest = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.REQUEST_PARSERS, node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} DCP type object. - */ -WMS._readDCPType = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.DCPTYPE_PARSERS, node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} HTTP object. - */ -WMS._readHTTP = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.HTTP_PARSERS, node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Operation type object. - */ -WMS._readOperationType = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.OPERATIONTYPE_PARSERS, node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Online resource object. - */ -WMS._readSizedFormatOnlineresource = function(node, objectStack) { - var formatOnlineresource = WMS._readFormatOnlineresource(node, objectStack); - if (isDef(formatOnlineresource)) { - var readNonNegativeIntegerString = XSD.readNonNegativeIntegerString; - var size = [ - readNonNegativeIntegerString(node.getAttribute('width')), - readNonNegativeIntegerString(node.getAttribute('height')) - ]; - formatOnlineresource['size'] = size; - return formatOnlineresource; - } - return undefined; -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Authority URL object. - */ -WMS._readAuthorityURL = function(node, objectStack) { - var authorityObject = WMS._readFormatOnlineresource(node, objectStack); - if (isDef(authorityObject)) { - authorityObject['name'] = node.getAttribute('name'); - return authorityObject; - } - return undefined; -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Metadata URL object. - */ -WMS._readMetadataURL = function(node, objectStack) { - var metadataObject = WMS._readFormatOnlineresource(node, objectStack); - if (isDef(metadataObject)) { - metadataObject['type'] = node.getAttribute('type'); - return metadataObject; - } - return undefined; -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Object|undefined} Style object. - */ -WMS._readStyle = function(node, objectStack) { - return XMLParser.pushParseAndPop({}, WMS.STYLE_PARSERS, node, objectStack); -}; - - -/** - * @private - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @return {Array.|undefined} Keyword list. - */ -WMS._readKeywordList = function(node, objectStack) { - return XMLParser.pushParseAndPop( - [], WMS.KEYWORDLIST_PARSERS, node, objectStack); -}; - -/** - * @const - * @type {Array.} - */ -WMS.NAMESPACE_URIS = [ - null, - 'http://www.opengis.net/wms' -]; - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Service': makePropertySetter(WMS._readService), - 'Capability': makePropertySetter(WMS._readCapability) - }); - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.CAPABILITY_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Request': makePropertySetter(WMS._readRequest), - 'Exception': makePropertySetter(WMS._readException), - 'Layer': makePropertySetter(WMS._readCapabilityLayer) - }); - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.SERVICE_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Name': makePropertySetter(XSD.readString), - 'Title': makePropertySetter(XSD.readString), - 'Abstract': makePropertySetter(XSD.readString), - 'KeywordList': makePropertySetter(WMS._readKeywordList), - 'OnlineResource': makePropertySetter(XLink.readHref), - 'ContactInformation': makePropertySetter(WMS._readContactInformation), - 'Fees': makePropertySetter(XSD.readString), - 'AccessConstraints': makePropertySetter(XSD.readString), - 'LayerLimit': makePropertySetter(XSD.readNonNegativeInteger), - 'MaxWidth': makePropertySetter(XSD.readNonNegativeInteger), - 'MaxHeight': makePropertySetter(XSD.readNonNegativeInteger) - }); - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.CONTACT_INFORMATION_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'ContactPersonPrimary': makePropertySetter(WMS._readContactPersonPrimary), - 'ContactPosition': makePropertySetter(XSD.readString), - 'ContactAddress': makePropertySetter(WMS._readContactAddress), - 'ContactVoiceTelephone': makePropertySetter(XSD.readString), - 'ContactFacsimileTelephone': makePropertySetter(XSD.readString), - 'ContactElectronicMailAddress': makePropertySetter(XSD.readString) - }); - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.CONTACT_PERSON_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'ContactPerson': makePropertySetter(XSD.readString), - 'ContactOrganization': makePropertySetter(XSD.readString) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.CONTACT_ADDRESS_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'AddressType': makePropertySetter(XSD.readString), - 'Address': makePropertySetter(XSD.readString), - 'City': makePropertySetter(XSD.readString), - 'StateOrProvince': makePropertySetter(XSD.readString), - 'PostCode': makePropertySetter(XSD.readString), - 'Country': makePropertySetter(XSD.readString) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.EXCEPTION_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Format': XMLParser.makeArrayPusher(XSD.readString) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.LAYER_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Name': makePropertySetter(XSD.readString), - 'Title': makePropertySetter(XSD.readString), - 'Abstract': makePropertySetter(XSD.readString), - 'KeywordList': makePropertySetter(WMS._readKeywordList), - 'CRS': XMLParser.makeObjectPropertyPusher(XSD.readString), - 'EX_GeographicBoundingBox': makePropertySetter(WMS._readEXGeographicBoundingBox), - 'BoundingBox': XMLParser.makeObjectPropertyPusher(WMS._readBoundingBox), - 'Dimension': XMLParser.makeObjectPropertyPusher(WMS._readDimension), - 'Attribution': makePropertySetter(WMS._readAttribution), - 'AuthorityURL': XMLParser.makeObjectPropertyPusher(WMS._readAuthorityURL), - 'Identifier': XMLParser.makeObjectPropertyPusher(XSD.readString), - 'MetadataURL': XMLParser.makeObjectPropertyPusher(WMS._readMetadataURL), - 'DataURL': XMLParser.makeObjectPropertyPusher(WMS._readFormatOnlineresource), - 'FeatureListURL': XMLParser.makeObjectPropertyPusher(WMS._readFormatOnlineresource), - 'Style': XMLParser.makeObjectPropertyPusher(WMS._readStyle), - 'MinScaleDenominator': makePropertySetter(XSD.readDecimal), - 'MaxScaleDenominator': makePropertySetter(XSD.readDecimal), - 'Layer': XMLParser.makeObjectPropertyPusher(WMS._readLayer) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.ATTRIBUTION_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Title': makePropertySetter(XSD.readString), - 'OnlineResource': makePropertySetter(XLink.readHref), - 'LogoURL': makePropertySetter(WMS._readSizedFormatOnlineresource) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS = - XMLParser.makeParsersNS(WMS.NAMESPACE_URIS, { - 'westBoundLongitude': makePropertySetter( - XSD.readDecimal), - 'eastBoundLongitude': makePropertySetter( - XSD.readDecimal), - 'southBoundLatitude': makePropertySetter( - XSD.readDecimal), - 'northBoundLatitude': makePropertySetter( - XSD.readDecimal) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.REQUEST_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'GetCapabilities': makePropertySetter( - WMS._readOperationType), - 'GetMap': makePropertySetter( - WMS._readOperationType), - 'GetFeatureInfo': makePropertySetter( - WMS._readOperationType) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.OPERATIONTYPE_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Format': XMLParser.makeObjectPropertyPusher(XSD.readString), - 'DCPType': XMLParser.makeObjectPropertyPusher( - WMS._readDCPType) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.DCPTYPE_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'HTTP': makePropertySetter( - WMS._readHTTP) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.HTTP_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Get': makePropertySetter( - WMS._readFormatOnlineresource), - 'Post': makePropertySetter( - WMS._readFormatOnlineresource) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.STYLE_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Name': makePropertySetter(XSD.readString), - 'Title': makePropertySetter(XSD.readString), - 'Abstract': makePropertySetter(XSD.readString), - 'LegendURL': XMLParser.makeObjectPropertyPusher(WMS._readSizedFormatOnlineresource), - 'StyleSheetURL': makePropertySetter(WMS._readFormatOnlineresource), - 'StyleURL': makePropertySetter(WMS._readFormatOnlineresource) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.FORMAT_ONLINERESOURCE_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Format': makePropertySetter(XSD.readString), - 'OnlineResource': makePropertySetter(XLink.readHref) - }); - - -/** - * @const - * @type {Object.>} - * @private - */ -WMS.KEYWORDLIST_PARSERS = XMLParser.makeParsersNS( - WMS.NAMESPACE_URIS, { - 'Keyword': XMLParser.makeArrayPusher(XSD.readString) - }); - -module.exports = WMS; - -},{"./node_types":"/Users/w8r/Projects/wms-capabilities/src/node_types.js","./utils/isdef":"/Users/w8r/Projects/wms-capabilities/src/utils/isdef.js","./utils/setifundefined":"/Users/w8r/Projects/wms-capabilities/src/utils/setifundefined.js","./xlink":"/Users/w8r/Projects/wms-capabilities/src/xlink.js","./xml_parser":"/Users/w8r/Projects/wms-capabilities/src/xml_parser.js","./xsd":"/Users/w8r/Projects/wms-capabilities/src/xsd.js"}],"/Users/w8r/Projects/wms-capabilities/src/xlink.js":[function(require,module,exports){ -"use strict"; - -/** - * @const - * @type {string} - */ -var NAMESPACE_URI = 'http://www.w3.org/1999/xlink'; - -module.exports = { - - /** - * @param {Node} node Node. - * @return {Boolean|undefined} Boolean. - */ - readHref: function(node) { - return node.getAttributeNS(NAMESPACE_URI, 'href'); - } -}; - -},{}],"/Users/w8r/Projects/wms-capabilities/src/xml_parser.js":[function(require,module,exports){ -"use strict"; - -var isDef = require('./utils/isdef'); -var setIfUndefined = require('./utils/setifundefined'); -var nodeTypes = require('./node_types'); - -/** - * XML DOM parser - * @constructor - */ -function XMLParser() { - - /** - * @type {DOMParser} - */ - this._parser = new DOMParser(); -}; - -/** - * @param {String} xmlstring - * @return {Document} - */ -XMLParser.prototype.toDocument = function(xmlstring) { - return this._parser.parseFromString(xmlstring, 'application/xml'); -}; - -/** - * Recursively grab all text content of child nodes into a single string. - * @param {Node} node Node. - * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line - * breaks. - * @return {string} All text content. - * @api - */ -XMLParser.getAllTextContent = function(node, normalizeWhitespace) { - return XMLParser.getAllTextContent_(node, normalizeWhitespace, []).join(''); -}; - - -/** - * @param {Node} node Node. - * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line - * breaks. - * @param {Array.} accumulator Accumulator. - * @private - * @return {Array.} Accumulator. - */ -XMLParser.getAllTextContent_ = function(node, normalizeWhitespace, accumulator) { - if (node.nodeType === nodeTypes.CDATA_SECTION || - node.nodeType === nodeTypes.TEXT) { - if (normalizeWhitespace) { - // FIXME understand why goog.dom.getTextContent_ uses String here - accumulator.push(String(node.nodeValue).replace(/(\r\n|\r|\n)/g, '')); - } else { - accumulator.push(node.nodeValue); - } - } else { - var n; - for (n = node.firstChild; n; n = n.nextSibling) { - XMLParser.getAllTextContent_(n, normalizeWhitespace, accumulator); - } - } - return accumulator; -}; - -/** - * @param {Object.>} parsersNS - * Parsers by namespace. - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @param {*=} bind The object to use as `this`. - */ -XMLParser.parseNode = function(parsersNS, node, objectStack, bind) { - for (var n = XMLParser.firstElementChild(node); n; n = XMLParser.nextElementSibling(n)) { - var namespaceURI = n.namespaceURI || null; - var parsers = parsersNS[namespaceURI]; - if (isDef(parsers)) { - var parser = parsers[n.localName]; - if (isDef(parser)) { - parser.call(bind, n, objectStack); - } - } - } -}; - -/** - * Mostly for node.js - * @param {Node} node - * @return {Node} - */ -XMLParser.firstElementChild = function(node) { - var firstElementChild = node.firstElementChild || node.firstChild; - while (firstElementChild && firstElementChild.nodeType !== nodeTypes.ELEMENT) { - firstElementChild = firstElementChild.nextSibling; - } - return firstElementChild; -}; - -/** - * Mostly for node.js - * @param {Node} node - * @return {Node} - */ -XMLParser.nextElementSibling = function(node) { - var nextElementSibling = node.nextElementSibling || node.nextSibling; - while (nextElementSibling && nextElementSibling.nodeType !== nodeTypes.ELEMENT) { - nextElementSibling = nextElementSibling.nextSibling; - } - return nextElementSibling; -}; - -/** - * @param {Array.} namespaceURIs Namespace URIs. - * @param {Object.} parsers Parsers. - * @param {Object.>=} opt_parsersNS - * ParsersNS. - * @return {Object.>} Parsers NS. - */ -XMLParser.makeParsersNS = function(namespaceURIs, parsers, opt_parsersNS) { - return /** @type {Object.>} */ ( - XMLParser.makeStructureNS(namespaceURIs, parsers, opt_parsersNS)); -}; - -/** - * Creates a namespaced structure, using the same values for each namespace. - * This can be used as a starting point for versioned parsers, when only a few - * values are version specific. - * @param {Array.} namespaceURIs Namespace URIs. - * @param {T} structure Structure. - * @param {Object.=} opt_structureNS Namespaced structure to add to. - * @return {Object.} Namespaced structure. - * @template T - */ -XMLParser.makeStructureNS = function(namespaceURIs, structure, opt_structureNS) { - /** - * @type {Object.} - */ - var structureNS = isDef(opt_structureNS) ? opt_structureNS : {}; - var i, ii; - for (i = 0, ii = namespaceURIs.length; i < ii; ++i) { - structureNS[namespaceURIs[i]] = structure; - } - return structureNS; -}; - -/** - * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. - * @param {string=} opt_property Property. - * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {XMLParser.Parser} Parser. - * @template T - */ -XMLParser.makeObjectPropertySetter = function(valueReader, opt_property, opt_this) { - return ( - /** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - */ - function(node, objectStack) { - var value = valueReader.call(isDef(opt_this) ? opt_this : this, - node, objectStack); - if (isDef(value)) { - var object = /** @type {Object} */ (objectStack[objectStack.length - 1]); - var property = isDef(opt_property) ? opt_property : node.localName; - object[property] = value; - } - }); -}; - -/** - * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. - * @param {string=} opt_property Property. - * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {Function} Parser. - * @template T - */ -XMLParser.makeObjectPropertyPusher = function(valueReader, opt_property, opt_this) { - return ( - /** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - */ - function(node, objectStack) { - var value = valueReader.call(isDef(opt_this) ? opt_this : this, - node, objectStack); - - if (isDef(value)) { - var object = /** @type {Object} */ (objectStack[objectStack.length - 1]); - var property = isDef(opt_property) ? opt_property : node.localName; - var array = setIfUndefined(object, property, []); - array.push(value); - } - }); -}; - -/** - * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. - * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {Function} Parser. - * @template T - */ -XMLParser.makeArrayPusher = function(valueReader, opt_this) { - return ( - /** - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - */ - function(node, objectStack) { - var value = valueReader.call(isDef(opt_this) ? opt_this : this, - node, objectStack); - if (isDef(value)) { - var array = objectStack[objectStack.length - 1]; - array.push(value); - } - }); -}; - -/** - * @param {Object} object Object. - * @param {Object.>} parsersNS Parsers by namespace. - * @param {Node} node Node. - * @param {Array.<*>} objectStack Object stack. - * @param {*=} bind The object to use as `this`. - * @return {Object|undefined} Object. - */ -XMLParser.pushParseAndPop = function(object, parsersNS, node, objectStack, bind) { - objectStack.push(object); - XMLParser.parseNode(parsersNS, node, objectStack, bind); - return objectStack.pop(); -}; - -module.exports = XMLParser; - -},{"./node_types":"/Users/w8r/Projects/wms-capabilities/src/node_types.js","./utils/isdef":"/Users/w8r/Projects/wms-capabilities/src/utils/isdef.js","./utils/setifundefined":"/Users/w8r/Projects/wms-capabilities/src/utils/setifundefined.js"}],"/Users/w8r/Projects/wms-capabilities/src/xsd.js":[function(require,module,exports){ -"use strict"; - -var isDef = require('./utils/isdef'); -var string = require('./utils/string'); -var XMLParser = require('./xml_parser'); - -var XSD = {}; - -/** - * @const - * @type {string} - */ -XSD.NAMESPACE_URI = 'http://www.w3.org/2001/XMLSchema'; - -/** - * @param {Node} node Node. - * @return {boolean|undefined} Boolean. - */ -XSD.readBoolean = function(node) { - var s = XMLParser.getAllTextContent(node, false); - return XSD.readBooleanString(s); -}; - -/** - * @param {string} string String. - * @return {boolean|undefined} Boolean. - */ -XSD.readBooleanString = function(string) { - var m = /^\s*(true|1)|(false|0)\s*$/.exec(string); - if (m) { - return isDef(m[1]) || false; - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @return {number|undefined} DateTime in seconds. - */ -XSD.readDateTime = function(node) { - var s = XMLParser.getAllTextContent(node, false); - var re = /^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(?:([+\-])(\d{2})(?::(\d{2}))?))\s*$/; - var m = re.exec(s); - if (m) { - var year = parseInt(m[1], 10); - var month = parseInt(m[2], 10) - 1; - var day = parseInt(m[3], 10); - var hour = parseInt(m[4], 10); - var minute = parseInt(m[5], 10); - var second = parseInt(m[6], 10); - var dateTime = Date.UTC(year, month, day, hour, minute, second) / 1000; - if (m[7] != 'Z') { - var sign = m[8] == '-' ? -1 : 1; - dateTime += sign * 60 * parseInt(m[9], 10); - if (isDef(m[10])) { - dateTime += sign * 60 * 60 * parseInt(m[10], 10); - } - } - return dateTime; - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @return {number|undefined} Decimal. - */ -XSD.readDecimal = function(node) { - var s = XMLParser.getAllTextContent(node, false); - return XSD.readDecimalString(s); -}; - - -/** - * @param {string} string String. - * @return {number|undefined} Decimal. - */ -XSD.readDecimalString = function(string) { - // FIXME check spec - var m = /^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*$/i.exec(string); - if (m) { - return parseFloat(m[1]); - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @return {number|undefined} Non negative integer. - */ -XSD.readNonNegativeInteger = function(node) { - var s = XMLParser.getAllTextContent(node, false); - return XSD.readNonNegativeIntegerString(s); -}; - - -/** - * @param {string} string String. - * @return {number|undefined} Non negative integer. - */ -XSD.readNonNegativeIntegerString = function(string) { - var m = /^\s*(\d+)\s*$/.exec(string); - if (m) { - return parseInt(m[1], 10); - } else { - return undefined; - } -}; - - -/** - * @param {Node} node Node. - * @return {string|undefined} String. - */ -XSD.readString = function(node) { - var s = XMLParser.getAllTextContent(node, false); - return string.trim(s); -}; - - -/** - * @param {Node} node Node to append a TextNode with the boolean to. - * @param {boolean} bool Boolean. - */ -XSD.writeBooleanTextNode = function(node, bool) { - XSD.writeStringTextNode(node, (bool) ? '1' : '0'); -}; - - -/** - * @param {Node} node Node to append a TextNode with the dateTime to. - * @param {number} dateTime DateTime in seconds. - */ -XSD.writeDateTimeTextNode = function(node, dateTime) { - var date = new Date(dateTime * 1000); - var string = date.getUTCFullYear() + '-' + - string.padNumber(date.getUTCMonth() + 1, 2) + '-' + - string.padNumber(date.getUTCDate(), 2) + 'T' + - string.padNumber(date.getUTCHours(), 2) + ':' + - string.padNumber(date.getUTCMinutes(), 2) + ':' + - string.padNumber(date.getUTCSeconds(), 2) + 'Z'; - node.appendChild(XMLParser.DOCUMENT.createTextNode(string)); -}; - - -/** - * @param {Node} node Node to append a TextNode with the decimal to. - * @param {number} decimal Decimal. - */ -XSD.writeDecimalTextNode = function(node, decimal) { - var string = decimal.toPrecision(); - node.appendChild(XMLParser.DOCUMENT.createTextNode(string)); -}; - - -/** - * @param {Node} node Node to append a TextNode with the decimal to. - * @param {number} nonNegativeInteger Non negative integer. - */ -XSD.writeNonNegativeIntegerTextNode = function(node, nonNegativeInteger) { - var string = nonNegativeInteger.toString(); - node.appendChild(XMLParser.DOCUMENT.createTextNode(string)); -}; - - -/** - * @param {Node} node Node to append a TextNode with the string to. - * @param {string} string String. - */ -XSD.writeStringTextNode = function(node, string) { - node.appendChild(XMLParser.DOCUMENT.createTextNode(string)); -}; - -module.exports = XSD; - -},{"./utils/isdef":"/Users/w8r/Projects/wms-capabilities/src/utils/isdef.js","./utils/string":"/Users/w8r/Projects/wms-capabilities/src/utils/string.js","./xml_parser":"/Users/w8r/Projects/wms-capabilities/src/xml_parser.js"}]},{},["/Users/w8r/Projects/wms-capabilities/example/js/app.js"]) -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiZXhhbXBsZS9qcy9hcHAuanMiLCJleGFtcGxlL2pzL2pzb24tZm9ybWF0LmpzIiwiZXhhbXBsZS9qcy94bWwtZm9ybWF0LmpzIiwiaW5kZXguanMiLCJub2RlX21vZHVsZXMvcmVxd2VzdC9yZXF3ZXN0LmpzIiwibm9kZV9tb2R1bGVzL3NwaW4uanMvc3Bpbi5qcyIsInNyYy9ub2RlX3R5cGVzLmpzIiwic3JjL3V0aWxzL2lzZGVmLmpzIiwic3JjL3V0aWxzL3NldGlmdW5kZWZpbmVkLmpzIiwic3JjL3V0aWxzL3N0cmluZy5qcyIsInNyYy93bXMuanMiLCJzcmMveGxpbmsuanMiLCJzcmMveG1sX3BhcnNlci5qcyIsInNyYy94c2QuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzdEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdm1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsdUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJ2YXIganNvbkZvcm1hdCA9IGdsb2JhbC5qc29uRm9ybWF0ID0gcmVxdWlyZSgnLi9qc29uLWZvcm1hdCcpO1xudmFyIHhtbEZvcm1hdCA9IGdsb2JhbC54bWxGb3JtYXQgPSByZXF1aXJlKCcuL3htbC1mb3JtYXQnKTtcbnZhciBXTVNDYXBhYmlsaXRpZXMgPSBnbG9iYWwuV01TQ2FwYWJpbGl0aWVzIHx8IHJlcXVpcmUoJy4uLy4uL2luZGV4Jyk7XG52YXIgU3Bpbm5lciA9IHJlcXVpcmUoJ3NwaW4uanMnKTtcbnZhciByZXF3ZXN0ID0gZ2xvYmFsLnJlcXdlc3QgPSByZXF1aXJlKCdyZXF3ZXN0Jyk7XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG52YXIgc2VydmljZVNlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXJ2aWNlJyk7XG52YXIgeG1sID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3htbCcpO1xudmFyIGpzb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnanNvbicpO1xudmFyIGlucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2lucHV0LWFyZWEnKTtcblxuLy8gdGhlIG9ubHkgb3BlbiBDT1JTIHByb3h5IEkgY291bGQgZmluZFxudmFyIHByb3h5ID0gXCJodHRwczovL3F1ZXJ5LnlhaG9vYXBpcy5jb20vdjEvcHVibGljL3lxbFwiO1xudmFyIHBhcnNlciA9IG5ldyBXTVNDYXBhYmlsaXRpZXMoKTtcblxuZnVuY3Rpb24gc2hvd0lucHV0KCkge1xuICB4bWwuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgaW5wdXQuc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xufVxuXG5mdW5jdGlvbiBoaWRlSW5wdXQoKSB7XG4gIHhtbC5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gIGlucHV0LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZSh4bWxTdHJpbmcpIHtcbiAgeG1sLnRleHRDb250ZW50ID0geG1sRm9ybWF0KHhtbFN0cmluZyk7XG4gIFByaXNtLmhpZ2hsaWdodEVsZW1lbnQoeG1sKTtcblxuICBqc29uLnRleHRDb250ZW50ID0ganNvbkZvcm1hdChKU09OLnN0cmluZ2lmeShwYXJzZXIucGFyc2UoeG1sU3RyaW5nKSkpO1xuICBQcmlzbS5oaWdobGlnaHRFbGVtZW50KGpzb24pO1xufVxuXG5zZXJ2aWNlU2VsZWN0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uKCkge1xuICBpZiAoc2VydmljZVNlbGVjdC52YWx1ZSAhPT0gJycpIHtcbiAgICBoaWRlSW5wdXQoKTtcblxuICAgIHJlcXdlc3Qoe1xuICAgICAgdXJsOiBwcm94eSxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgcTogJ3NlbGVjdCAqIGZyb20geG1sIHdoZXJlIHVybD1cIicgK1xuICAgICAgICAgIHNlcnZpY2VTZWxlY3QudmFsdWUucmVwbGFjZSgvXFwmYW1wXFw7L2csICcmJykgKyAnXCInXG4gICAgICB9LFxuICAgICAgdHlwZTogXCJ4bWxcIixcbiAgICAgIGNyb3NzT3JpZ2luOiB0cnVlLFxuICAgICAgc3VjY2VzczogZnVuY3Rpb24oeG1sKSB7XG4gICAgICAgIHVwZGF0ZSh4bWwuZmlyc3RDaGlsZC5maXJzdENoaWxkLmlubmVySFRNTCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn0sIGZhbHNlKTtcblxueG1sLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgc2hvd0lucHV0LCBmYWxzZSk7XG5cbmlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ3Bhc3RlJywgZnVuY3Rpb24oKSB7XG4gIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgdXBkYXRlKGlucHV0LnZhbHVlKTtcbiAgICBoaWRlSW5wdXQoKTtcbiAgfSwgNTApO1xufSwgZmFsc2UpO1xuIiwiLypcbiAgICBqc29uLWZvcm1hdCB2LjEuMVxuICAgIGh0dHA6Ly9naXRodWIuY29tL3Bob2Jvc2xhYi9qc29uLWZvcm1hdFxuXG4gICAgUmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2U6XG4gICAgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcbiovXG5cbnZhciBwID0gW10sXG4gIHB1c2ggPSBmdW5jdGlvbihtKSB7XG4gICAgcmV0dXJuICdcXFxcJyArIHAucHVzaChtKSArICdcXFxcJztcbiAgfSxcbiAgcG9wID0gZnVuY3Rpb24obSwgaSkge1xuICAgIHJldHVybiBwW2kgLSAxXVxuICB9LFxuICB0YWJzID0gZnVuY3Rpb24oY291bnQpIHtcbiAgICByZXR1cm4gbmV3IEFycmF5KGNvdW50ICsgMSkuam9pbignXFx0Jyk7XG4gIH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oanNvbikge1xuICBwID0gW107XG4gIHZhciBvdXQgPSBcIlwiLFxuICAgIGluZGVudCA9IDA7XG5cbiAgLy8gRXh0cmFjdCBiYWNrc2xhc2hlcyBhbmQgc3RyaW5nc1xuICBqc29uID0ganNvblxuICAgIC5yZXBsYWNlKC9cXFxcLi9nLCBwdXNoKVxuICAgIC5yZXBsYWNlKC8oXCIuKj9cInwnLio/JykvZywgcHVzaClcbiAgICAucmVwbGFjZSgvXFxzKy8sICcnKTtcblxuICAvLyBJbmRlbnQgYW5kIGluc2VydCBuZXdsaW5lc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGpzb24ubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYyA9IGpzb24uY2hhckF0KGkpO1xuXG4gICAgc3dpdGNoIChjKSB7XG4gICAgICBjYXNlICd7JzpcbiAgICAgICAgb3V0ICs9IGMgKyBcIlxcblwiICsgdGFicygrK2luZGVudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnWyc6XG4gICAgICAgIG91dCArPSBjICsgXCJcXG5cIiArIHRhYnMoKytpbmRlbnQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ10nOlxuICAgICAgICBvdXQgKz0gXCJcXG5cIiArIHRhYnMoLS1pbmRlbnQpICsgYztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd9JzpcbiAgICAgICAgb3V0ICs9IFwiXFxuXCIgKyB0YWJzKC0taW5kZW50KSArIGM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnLCc6XG4gICAgICAgIGlmICgvXFxkLy50ZXN0KGpzb24uY2hhckF0KGkgLSAxKSkpIHtcbiAgICAgICAgICBvdXQgKz0gXCIsIFwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dCArPSBcIixcXG5cIiArIHRhYnMoaW5kZW50KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzonOlxuICAgICAgICBvdXQgKz0gXCI6IFwiO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIG91dCArPSBjO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyBTdHJpcCB3aGl0ZXNwYWNlIGZyb20gbnVtZXJpYyBhcnJheXMgYW5kIHB1dCBiYWNrc2xhc2hlc1xuICAvLyBhbmQgc3RyaW5ncyBiYWNrIGluXG4gIG91dCA9IG91dFxuICAgIC5yZXBsYWNlKC9cXFtbXFxkLFxcc10rP1xcXS9nLCBmdW5jdGlvbihtKSB7XG4gICAgICByZXR1cm4gbS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgIH0pXG4gICAgLy8gbnVtYmVyIGFycmF5c1xuICAgIC5yZXBsYWNlKC9cXFtcXHMqKFxcZCkvZywgZnVuY3Rpb24oYSwgYikge1xuICAgICAgcmV0dXJuICdbJyArIGI7XG4gICAgfSlcbiAgICAucmVwbGFjZSgvKFxcZClcXHMqXFxdL2csIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIHJldHVybiBiICsgJ10nO1xuICAgIH0pXG4gICAgLnJlcGxhY2UoL1xce1xccypcXH0vZywgJ3t9JykgLy8gZW1wdHkgb2JqZWN0c1xuICAgIC5yZXBsYWNlKC9cXFxcKFxcZCspXFxcXC9nLCBwb3ApIC8vIHN0cmluZ3NcbiAgICAucmVwbGFjZSgvXFxcXChcXGQrKVxcXFwvZywgcG9wKTsgLy8gYmFja3NsYXNoZXMgaW4gc3RyaW5nc1xuXG4gIHJldHVybiBvdXQ7XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oeG1sKSB7XG4gIHZhciBmb3JtYXR0ZWQgPSAnJztcbiAgdmFyIHJlZyA9IC8oPikoPCkoXFwvKikvZztcbiAgeG1sID0geG1sLnJlcGxhY2UocmVnLCAnJDFcXHJcXG4kMiQzJyk7XG4gIHZhciBwYWQgPSAwO1xuXG4gIHhtbC5zcGxpdCgnXFxyXFxuJykuZm9yRWFjaChmdW5jdGlvbihub2RlLCBpbmRleCkge1xuICAgIHZhciBpbmRlbnQgPSAwO1xuICAgIGlmIChub2RlLm1hdGNoKC8uKzxcXC9cXHdbXj5dKj4kLykpIHtcbiAgICAgIGluZGVudCA9IDA7XG4gICAgfSBlbHNlIGlmIChub2RlLm1hdGNoKC9ePFxcL1xcdy8pKSB7XG4gICAgICBpZiAocGFkICE9IDApIHtcbiAgICAgICAgcGFkIC09IDE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChub2RlLm1hdGNoKC9ePFxcd1tePl0qW15cXC9dPi4qJC8pKSB7XG4gICAgICBpbmRlbnQgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbmRlbnQgPSAwO1xuICAgIH1cblxuICAgIHZhciBwYWRkaW5nID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYWQ7IGkrKykge1xuICAgICAgcGFkZGluZyArPSAnICAnO1xuICAgIH1cblxuICAgIGZvcm1hdHRlZCArPSBwYWRkaW5nICsgbm9kZSArICdcXHJcXG4nO1xuICAgIHBhZCArPSBpbmRlbnQ7XG4gIH0pO1xuXG4gIHJldHVybiBmb3JtYXR0ZWQ7XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zcmMvd21zJyk7XG4iLCIvKiFcbiAgKiBSZXF3ZXN0ISBBIGdlbmVyYWwgcHVycG9zZSBYSFIgY29ubmVjdGlvbiBtYW5hZ2VyXG4gICogbGljZW5zZSBNSVQgKGMpIER1c3RpbiBEaWF6IDIwMTRcbiAgKiBodHRwczovL2dpdGh1Yi5jb20vZGVkL3JlcXdlc3RcbiAgKi9cblxuIWZ1bmN0aW9uIChuYW1lLCBjb250ZXh0LCBkZWZpbml0aW9uKSB7XG4gIGlmICh0eXBlb2YgbW9kdWxlICE9ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKVxuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkgZGVmaW5lKGRlZmluaXRpb24pXG4gIGVsc2UgY29udGV4dFtuYW1lXSA9IGRlZmluaXRpb24oKVxufSgncmVxd2VzdCcsIHRoaXMsIGZ1bmN0aW9uICgpIHtcblxuICB2YXIgd2luID0gd2luZG93XG4gICAgLCBkb2MgPSBkb2N1bWVudFxuICAgICwgaHR0cHNSZSA9IC9eaHR0cC9cbiAgICAsIHByb3RvY29sUmUgPSAvKF5cXHcrKTpcXC9cXC8vXG4gICAgLCB0d29IdW5kbyA9IC9eKDIwXFxkfDEyMjMpJC8gLy9odHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwMDQ2OTcyL21zaWUtcmV0dXJucy1zdGF0dXMtY29kZS1vZi0xMjIzLWZvci1hamF4LXJlcXVlc3RcbiAgICAsIGJ5VGFnID0gJ2dldEVsZW1lbnRzQnlUYWdOYW1lJ1xuICAgICwgcmVhZHlTdGF0ZSA9ICdyZWFkeVN0YXRlJ1xuICAgICwgY29udGVudFR5cGUgPSAnQ29udGVudC1UeXBlJ1xuICAgICwgcmVxdWVzdGVkV2l0aCA9ICdYLVJlcXVlc3RlZC1XaXRoJ1xuICAgICwgaGVhZCA9IGRvY1tieVRhZ10oJ2hlYWQnKVswXVxuICAgICwgdW5pcWlkID0gMFxuICAgICwgY2FsbGJhY2tQcmVmaXggPSAncmVxd2VzdF8nICsgKCtuZXcgRGF0ZSgpKVxuICAgICwgbGFzdFZhbHVlIC8vIGRhdGEgc3RvcmVkIGJ5IHRoZSBtb3N0IHJlY2VudCBKU09OUCBjYWxsYmFja1xuICAgICwgeG1sSHR0cFJlcXVlc3QgPSAnWE1MSHR0cFJlcXVlc3QnXG4gICAgLCB4RG9tYWluUmVxdWVzdCA9ICdYRG9tYWluUmVxdWVzdCdcbiAgICAsIG5vb3AgPSBmdW5jdGlvbiAoKSB7fVxuXG4gICAgLCBpc0FycmF5ID0gdHlwZW9mIEFycmF5LmlzQXJyYXkgPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IEFycmF5LmlzQXJyYXlcbiAgICAgICAgOiBmdW5jdGlvbiAoYSkge1xuICAgICAgICAgICAgcmV0dXJuIGEgaW5zdGFuY2VvZiBBcnJheVxuICAgICAgICAgIH1cblxuICAgICwgZGVmYXVsdEhlYWRlcnMgPSB7XG4gICAgICAgICAgJ2NvbnRlbnRUeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbiAgICAgICAgLCAncmVxdWVzdGVkV2l0aCc6IHhtbEh0dHBSZXF1ZXN0XG4gICAgICAgICwgJ2FjY2VwdCc6IHtcbiAgICAgICAgICAgICAgJyonOiAgJ3RleHQvamF2YXNjcmlwdCwgdGV4dC9odG1sLCBhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sLCAqLyonXG4gICAgICAgICAgICAsICd4bWwnOiAgJ2FwcGxpY2F0aW9uL3htbCwgdGV4dC94bWwnXG4gICAgICAgICAgICAsICdodG1sJzogJ3RleHQvaHRtbCdcbiAgICAgICAgICAgICwgJ3RleHQnOiAndGV4dC9wbGFpbidcbiAgICAgICAgICAgICwgJ2pzb24nOiAnYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0J1xuICAgICAgICAgICAgLCAnanMnOiAgICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0LCB0ZXh0L2phdmFzY3JpcHQnXG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgLCB4aHIgPSBmdW5jdGlvbihvKSB7XG4gICAgICAgIC8vIGlzIGl0IHgtZG9tYWluXG4gICAgICAgIGlmIChvWydjcm9zc09yaWdpbiddID09PSB0cnVlKSB7XG4gICAgICAgICAgdmFyIHhociA9IHdpblt4bWxIdHRwUmVxdWVzdF0gPyBuZXcgWE1MSHR0cFJlcXVlc3QoKSA6IG51bGxcbiAgICAgICAgICBpZiAoeGhyICYmICd3aXRoQ3JlZGVudGlhbHMnIGluIHhocikge1xuICAgICAgICAgICAgcmV0dXJuIHhoclxuICAgICAgICAgIH0gZWxzZSBpZiAod2luW3hEb21haW5SZXF1ZXN0XSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBYRG9tYWluUmVxdWVzdCgpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGNyb3NzLW9yaWdpbiByZXF1ZXN0cycpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHdpblt4bWxIdHRwUmVxdWVzdF0pIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJylcbiAgICAgICAgfVxuICAgICAgfVxuICAgICwgZ2xvYmFsU2V0dXBPcHRpb25zID0ge1xuICAgICAgICBkYXRhRmlsdGVyOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgIHJldHVybiBkYXRhXG4gICAgICAgIH1cbiAgICAgIH1cblxuICBmdW5jdGlvbiBzdWNjZWVkKHIpIHtcbiAgICB2YXIgcHJvdG9jb2wgPSBwcm90b2NvbFJlLmV4ZWMoci51cmwpO1xuICAgIHByb3RvY29sID0gKHByb3RvY29sICYmIHByb3RvY29sWzFdKSB8fCB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2w7XG4gICAgcmV0dXJuIGh0dHBzUmUudGVzdChwcm90b2NvbCkgPyB0d29IdW5kby50ZXN0KHIucmVxdWVzdC5zdGF0dXMpIDogISFyLnJlcXVlc3QucmVzcG9uc2U7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVSZWFkeVN0YXRlKHIsIHN1Y2Nlc3MsIGVycm9yKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHVzZSBfYWJvcnRlZCB0byBtaXRpZ2F0ZSBhZ2FpbnN0IElFIGVyciBjMDBjMDIzZlxuICAgICAgLy8gKGNhbid0IHJlYWQgcHJvcHMgb24gYWJvcnRlZCByZXF1ZXN0IG9iamVjdHMpXG4gICAgICBpZiAoci5fYWJvcnRlZCkgcmV0dXJuIGVycm9yKHIucmVxdWVzdClcbiAgICAgIGlmIChyLl90aW1lZE91dCkgcmV0dXJuIGVycm9yKHIucmVxdWVzdCwgJ1JlcXVlc3QgaXMgYWJvcnRlZDogdGltZW91dCcpXG4gICAgICBpZiAoci5yZXF1ZXN0ICYmIHIucmVxdWVzdFtyZWFkeVN0YXRlXSA9PSA0KSB7XG4gICAgICAgIHIucmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBub29wXG4gICAgICAgIGlmIChzdWNjZWVkKHIpKSBzdWNjZXNzKHIucmVxdWVzdClcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGVycm9yKHIucmVxdWVzdClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzZXRIZWFkZXJzKGh0dHAsIG8pIHtcbiAgICB2YXIgaGVhZGVycyA9IG9bJ2hlYWRlcnMnXSB8fCB7fVxuICAgICAgLCBoXG5cbiAgICBoZWFkZXJzWydBY2NlcHQnXSA9IGhlYWRlcnNbJ0FjY2VwdCddXG4gICAgICB8fCBkZWZhdWx0SGVhZGVyc1snYWNjZXB0J11bb1sndHlwZSddXVxuICAgICAgfHwgZGVmYXVsdEhlYWRlcnNbJ2FjY2VwdCddWycqJ11cblxuICAgIHZhciBpc0FGb3JtRGF0YSA9IHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJyAmJiAob1snZGF0YSddIGluc3RhbmNlb2YgRm9ybURhdGEpO1xuICAgIC8vIGJyZWFrcyBjcm9zcy1vcmlnaW4gcmVxdWVzdHMgd2l0aCBsZWdhY3kgYnJvd3NlcnNcbiAgICBpZiAoIW9bJ2Nyb3NzT3JpZ2luJ10gJiYgIWhlYWRlcnNbcmVxdWVzdGVkV2l0aF0pIGhlYWRlcnNbcmVxdWVzdGVkV2l0aF0gPSBkZWZhdWx0SGVhZGVyc1sncmVxdWVzdGVkV2l0aCddXG4gICAgaWYgKCFoZWFkZXJzW2NvbnRlbnRUeXBlXSAmJiAhaXNBRm9ybURhdGEpIGhlYWRlcnNbY29udGVudFR5cGVdID0gb1snY29udGVudFR5cGUnXSB8fCBkZWZhdWx0SGVhZGVyc1snY29udGVudFR5cGUnXVxuICAgIGZvciAoaCBpbiBoZWFkZXJzKVxuICAgICAgaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShoKSAmJiAnc2V0UmVxdWVzdEhlYWRlcicgaW4gaHR0cCAmJiBodHRwLnNldFJlcXVlc3RIZWFkZXIoaCwgaGVhZGVyc1toXSlcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldENyZWRlbnRpYWxzKGh0dHAsIG8pIHtcbiAgICBpZiAodHlwZW9mIG9bJ3dpdGhDcmVkZW50aWFscyddICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgaHR0cC53aXRoQ3JlZGVudGlhbHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBodHRwLndpdGhDcmVkZW50aWFscyA9ICEhb1snd2l0aENyZWRlbnRpYWxzJ11cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnZW5lcmFsQ2FsbGJhY2soZGF0YSkge1xuICAgIGxhc3RWYWx1ZSA9IGRhdGFcbiAgfVxuXG4gIGZ1bmN0aW9uIHVybGFwcGVuZCAodXJsLCBzKSB7XG4gICAgcmV0dXJuIHVybCArICgvXFw/Ly50ZXN0KHVybCkgPyAnJicgOiAnPycpICsgc1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlSnNvbnAobywgZm4sIGVyciwgdXJsKSB7XG4gICAgdmFyIHJlcUlkID0gdW5pcWlkKytcbiAgICAgICwgY2JrZXkgPSBvWydqc29ucENhbGxiYWNrJ10gfHwgJ2NhbGxiYWNrJyAvLyB0aGUgJ2NhbGxiYWNrJyBrZXlcbiAgICAgICwgY2J2YWwgPSBvWydqc29ucENhbGxiYWNrTmFtZSddIHx8IHJlcXdlc3QuZ2V0Y2FsbGJhY2tQcmVmaXgocmVxSWQpXG4gICAgICAsIGNicmVnID0gbmV3IFJlZ0V4cCgnKChefFxcXFw/fCYpJyArIGNia2V5ICsgJyk9KFteJl0rKScpXG4gICAgICAsIG1hdGNoID0gdXJsLm1hdGNoKGNicmVnKVxuICAgICAgLCBzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudCgnc2NyaXB0JylcbiAgICAgICwgbG9hZGVkID0gMFxuICAgICAgLCBpc0lFMTAgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ01TSUUgMTAuMCcpICE9PSAtMVxuXG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICBpZiAobWF0Y2hbM10gPT09ICc/Jykge1xuICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShjYnJlZywgJyQxPScgKyBjYnZhbCkgLy8gd2lsZGNhcmQgY2FsbGJhY2sgZnVuYyBuYW1lXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYnZhbCA9IG1hdGNoWzNdIC8vIHByb3ZpZGVkIGNhbGxiYWNrIGZ1bmMgbmFtZVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB1cmwgPSB1cmxhcHBlbmQodXJsLCBjYmtleSArICc9JyArIGNidmFsKSAvLyBubyBjYWxsYmFjayBkZXRhaWxzLCBhZGQgJ2VtXG4gICAgfVxuXG4gICAgd2luW2NidmFsXSA9IGdlbmVyYWxDYWxsYmFja1xuXG4gICAgc2NyaXB0LnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0J1xuICAgIHNjcmlwdC5zcmMgPSB1cmxcbiAgICBzY3JpcHQuYXN5bmMgPSB0cnVlXG4gICAgaWYgKHR5cGVvZiBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlICE9PSAndW5kZWZpbmVkJyAmJiAhaXNJRTEwKSB7XG4gICAgICAvLyBuZWVkIHRoaXMgZm9yIElFIGR1ZSB0byBvdXQtb2Ytb3JkZXIgb25yZWFkeXN0YXRlY2hhbmdlKCksIGJpbmRpbmcgc2NyaXB0XG4gICAgICAvLyBleGVjdXRpb24gdG8gYW4gZXZlbnQgbGlzdGVuZXIgZ2l2ZXMgdXMgY29udHJvbCBvdmVyIHdoZW4gdGhlIHNjcmlwdFxuICAgICAgLy8gaXMgZXhlY3V0ZWQuIFNlZSBodHRwOi8vamF1Ym91cmcubmV0LzIwMTAvMDcvbG9hZGluZy1zY3JpcHQtYXMtb25jbGljay1oYW5kbGVyLW9mLmh0bWxcbiAgICAgIHNjcmlwdC5odG1sRm9yID0gc2NyaXB0LmlkID0gJ19yZXF3ZXN0XycgKyByZXFJZFxuICAgIH1cblxuICAgIHNjcmlwdC5vbmxvYWQgPSBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKChzY3JpcHRbcmVhZHlTdGF0ZV0gJiYgc2NyaXB0W3JlYWR5U3RhdGVdICE9PSAnY29tcGxldGUnICYmIHNjcmlwdFtyZWFkeVN0YXRlXSAhPT0gJ2xvYWRlZCcpIHx8IGxvYWRlZCkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICAgIHNjcmlwdC5vbmxvYWQgPSBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbFxuICAgICAgc2NyaXB0Lm9uY2xpY2sgJiYgc2NyaXB0Lm9uY2xpY2soKVxuICAgICAgLy8gQ2FsbCB0aGUgdXNlciBjYWxsYmFjayB3aXRoIHRoZSBsYXN0IHZhbHVlIHN0b3JlZCBhbmQgY2xlYW4gdXAgdmFsdWVzIGFuZCBzY3JpcHRzLlxuICAgICAgZm4obGFzdFZhbHVlKVxuICAgICAgbGFzdFZhbHVlID0gdW5kZWZpbmVkXG4gICAgICBoZWFkLnJlbW92ZUNoaWxkKHNjcmlwdClcbiAgICAgIGxvYWRlZCA9IDFcbiAgICB9XG5cbiAgICAvLyBBZGQgdGhlIHNjcmlwdCB0byB0aGUgRE9NIGhlYWRcbiAgICBoZWFkLmFwcGVuZENoaWxkKHNjcmlwdClcblxuICAgIC8vIEVuYWJsZSBKU09OUCB0aW1lb3V0XG4gICAgcmV0dXJuIHtcbiAgICAgIGFib3J0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbFxuICAgICAgICBlcnIoe30sICdSZXF1ZXN0IGlzIGFib3J0ZWQ6IHRpbWVvdXQnLCB7fSlcbiAgICAgICAgbGFzdFZhbHVlID0gdW5kZWZpbmVkXG4gICAgICAgIGhlYWQucmVtb3ZlQ2hpbGQoc2NyaXB0KVxuICAgICAgICBsb2FkZWQgPSAxXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0UmVxdWVzdChmbiwgZXJyKSB7XG4gICAgdmFyIG8gPSB0aGlzLm9cbiAgICAgICwgbWV0aG9kID0gKG9bJ21ldGhvZCddIHx8ICdHRVQnKS50b1VwcGVyQ2FzZSgpXG4gICAgICAsIHVybCA9IHR5cGVvZiBvID09PSAnc3RyaW5nJyA/IG8gOiBvWyd1cmwnXVxuICAgICAgLy8gY29udmVydCBub24tc3RyaW5nIG9iamVjdHMgdG8gcXVlcnktc3RyaW5nIGZvcm0gdW5sZXNzIG9bJ3Byb2Nlc3NEYXRhJ10gaXMgZmFsc2VcbiAgICAgICwgZGF0YSA9IChvWydwcm9jZXNzRGF0YSddICE9PSBmYWxzZSAmJiBvWydkYXRhJ10gJiYgdHlwZW9mIG9bJ2RhdGEnXSAhPT0gJ3N0cmluZycpXG4gICAgICAgID8gcmVxd2VzdC50b1F1ZXJ5U3RyaW5nKG9bJ2RhdGEnXSlcbiAgICAgICAgOiAob1snZGF0YSddIHx8IG51bGwpXG4gICAgICAsIGh0dHBcbiAgICAgICwgc2VuZFdhaXQgPSBmYWxzZVxuXG4gICAgLy8gaWYgd2UncmUgd29ya2luZyBvbiBhIEdFVCByZXF1ZXN0IGFuZCB3ZSBoYXZlIGRhdGEgdGhlbiB3ZSBzaG91bGQgYXBwZW5kXG4gICAgLy8gcXVlcnkgc3RyaW5nIHRvIGVuZCBvZiBVUkwgYW5kIG5vdCBwb3N0IGRhdGFcbiAgICBpZiAoKG9bJ3R5cGUnXSA9PSAnanNvbnAnIHx8IG1ldGhvZCA9PSAnR0VUJykgJiYgZGF0YSkge1xuICAgICAgdXJsID0gdXJsYXBwZW5kKHVybCwgZGF0YSlcbiAgICAgIGRhdGEgPSBudWxsXG4gICAgfVxuXG4gICAgaWYgKG9bJ3R5cGUnXSA9PSAnanNvbnAnKSByZXR1cm4gaGFuZGxlSnNvbnAobywgZm4sIGVyciwgdXJsKVxuXG4gICAgLy8gZ2V0IHRoZSB4aHIgZnJvbSB0aGUgZmFjdG9yeSBpZiBwYXNzZWRcbiAgICAvLyBpZiB0aGUgZmFjdG9yeSByZXR1cm5zIG51bGwsIGZhbGwtYmFjayB0byBvdXJzXG4gICAgaHR0cCA9IChvLnhociAmJiBvLnhocihvKSkgfHwgeGhyKG8pXG5cbiAgICBodHRwLm9wZW4obWV0aG9kLCB1cmwsIG9bJ2FzeW5jJ10gPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlKVxuICAgIHNldEhlYWRlcnMoaHR0cCwgbylcbiAgICBzZXRDcmVkZW50aWFscyhodHRwLCBvKVxuICAgIGlmICh3aW5beERvbWFpblJlcXVlc3RdICYmIGh0dHAgaW5zdGFuY2VvZiB3aW5beERvbWFpblJlcXVlc3RdKSB7XG4gICAgICAgIGh0dHAub25sb2FkID0gZm5cbiAgICAgICAgaHR0cC5vbmVycm9yID0gZXJyXG4gICAgICAgIC8vIE5PVEU6IHNlZVxuICAgICAgICAvLyBodHRwOi8vc29jaWFsLm1zZG4ubWljcm9zb2Z0LmNvbS9Gb3J1bXMvZW4tVVMvaWV3ZWJkZXZlbG9wbWVudC90aHJlYWQvMzBlZjNhZGQtNzY3Yy00NDM2LWI4YTktZjFjYTE5YjQ4MTJlXG4gICAgICAgIGh0dHAub25wcm9ncmVzcyA9IGZ1bmN0aW9uKCkge31cbiAgICAgICAgc2VuZFdhaXQgPSB0cnVlXG4gICAgfSBlbHNlIHtcbiAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gaGFuZGxlUmVhZHlTdGF0ZSh0aGlzLCBmbiwgZXJyKVxuICAgIH1cbiAgICBvWydiZWZvcmUnXSAmJiBvWydiZWZvcmUnXShodHRwKVxuICAgIGlmIChzZW5kV2FpdCkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGh0dHAuc2VuZChkYXRhKVxuICAgICAgfSwgMjAwKVxuICAgIH0gZWxzZSB7XG4gICAgICBodHRwLnNlbmQoZGF0YSlcbiAgICB9XG4gICAgcmV0dXJuIGh0dHBcbiAgfVxuXG4gIGZ1bmN0aW9uIFJlcXdlc3QobywgZm4pIHtcbiAgICB0aGlzLm8gPSBvXG4gICAgdGhpcy5mbiA9IGZuXG5cbiAgICBpbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFR5cGUoaGVhZGVyKSB7XG4gICAgLy8ganNvbiwgamF2YXNjcmlwdCwgdGV4dC9wbGFpbiwgdGV4dC9odG1sLCB4bWxcbiAgICBpZiAoaGVhZGVyLm1hdGNoKCdqc29uJykpIHJldHVybiAnanNvbidcbiAgICBpZiAoaGVhZGVyLm1hdGNoKCdqYXZhc2NyaXB0JykpIHJldHVybiAnanMnXG4gICAgaWYgKGhlYWRlci5tYXRjaCgndGV4dCcpKSByZXR1cm4gJ2h0bWwnXG4gICAgaWYgKGhlYWRlci5tYXRjaCgneG1sJykpIHJldHVybiAneG1sJ1xuICB9XG5cbiAgZnVuY3Rpb24gaW5pdChvLCBmbikge1xuXG4gICAgdGhpcy51cmwgPSB0eXBlb2YgbyA9PSAnc3RyaW5nJyA/IG8gOiBvWyd1cmwnXVxuICAgIHRoaXMudGltZW91dCA9IG51bGxcblxuICAgIC8vIHdoZXRoZXIgcmVxdWVzdCBoYXMgYmVlbiBmdWxmaWxsZWQgZm9yIHB1cnBvc2VcbiAgICAvLyBvZiB0cmFja2luZyB0aGUgUHJvbWlzZXNcbiAgICB0aGlzLl9mdWxmaWxsZWQgPSBmYWxzZVxuICAgIC8vIHN1Y2Nlc3MgaGFuZGxlcnNcbiAgICB0aGlzLl9zdWNjZXNzSGFuZGxlciA9IGZ1bmN0aW9uKCl7fVxuICAgIHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcnMgPSBbXVxuICAgIC8vIGVycm9yIGhhbmRsZXJzXG4gICAgdGhpcy5fZXJyb3JIYW5kbGVycyA9IFtdXG4gICAgLy8gY29tcGxldGUgKGJvdGggc3VjY2VzcyBhbmQgZmFpbCkgaGFuZGxlcnNcbiAgICB0aGlzLl9jb21wbGV0ZUhhbmRsZXJzID0gW11cbiAgICB0aGlzLl9lcnJlZCA9IGZhbHNlXG4gICAgdGhpcy5fcmVzcG9uc2VBcmdzID0ge31cblxuICAgIHZhciBzZWxmID0gdGhpc1xuXG4gICAgZm4gPSBmbiB8fCBmdW5jdGlvbiAoKSB7fVxuXG4gICAgaWYgKG9bJ3RpbWVvdXQnXSkge1xuICAgICAgdGhpcy50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRpbWVkT3V0KClcbiAgICAgIH0sIG9bJ3RpbWVvdXQnXSlcbiAgICB9XG5cbiAgICBpZiAob1snc3VjY2VzcyddKSB7XG4gICAgICB0aGlzLl9zdWNjZXNzSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgb1snc3VjY2VzcyddLmFwcGx5KG8sIGFyZ3VtZW50cylcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob1snZXJyb3InXSkge1xuICAgICAgdGhpcy5fZXJyb3JIYW5kbGVycy5wdXNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgb1snZXJyb3InXS5hcHBseShvLCBhcmd1bWVudHMpXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChvWydjb21wbGV0ZSddKSB7XG4gICAgICB0aGlzLl9jb21wbGV0ZUhhbmRsZXJzLnB1c2goZnVuY3Rpb24gKCkge1xuICAgICAgICBvWydjb21wbGV0ZSddLmFwcGx5KG8sIGFyZ3VtZW50cylcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY29tcGxldGUgKHJlc3ApIHtcbiAgICAgIG9bJ3RpbWVvdXQnXSAmJiBjbGVhclRpbWVvdXQoc2VsZi50aW1lb3V0KVxuICAgICAgc2VsZi50aW1lb3V0ID0gbnVsbFxuICAgICAgd2hpbGUgKHNlbGYuX2NvbXBsZXRlSGFuZGxlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBzZWxmLl9jb21wbGV0ZUhhbmRsZXJzLnNoaWZ0KCkocmVzcClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdWNjZXNzIChyZXNwKSB7XG4gICAgICB2YXIgdHlwZSA9IG9bJ3R5cGUnXSB8fCByZXNwICYmIHNldFR5cGUocmVzcC5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJykpIC8vIHJlc3AgY2FuIGJlIHVuZGVmaW5lZCBpbiBJRVxuICAgICAgcmVzcCA9ICh0eXBlICE9PSAnanNvbnAnKSA/IHNlbGYucmVxdWVzdCA6IHJlc3BcbiAgICAgIC8vIHVzZSBnbG9iYWwgZGF0YSBmaWx0ZXIgb24gcmVzcG9uc2UgdGV4dFxuICAgICAgdmFyIGZpbHRlcmVkUmVzcG9uc2UgPSBnbG9iYWxTZXR1cE9wdGlvbnMuZGF0YUZpbHRlcihyZXNwLnJlc3BvbnNlVGV4dCwgdHlwZSlcbiAgICAgICAgLCByID0gZmlsdGVyZWRSZXNwb25zZVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzcC5yZXNwb25zZVRleHQgPSByXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGNhbid0IGFzc2lnbiB0aGlzIGluIElFPD04LCBqdXN0IGlnbm9yZVxuICAgICAgfVxuICAgICAgaWYgKHIpIHtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgJ2pzb24nOlxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNwID0gd2luLkpTT04gPyB3aW4uSlNPTi5wYXJzZShyKSA6IGV2YWwoJygnICsgciArICcpJylcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBlcnJvcihyZXNwLCAnQ291bGQgbm90IHBhcnNlIEpTT04gaW4gcmVzcG9uc2UnLCBlcnIpXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ2pzJzpcbiAgICAgICAgICByZXNwID0gZXZhbChyKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgJ2h0bWwnOlxuICAgICAgICAgIHJlc3AgPSByXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAneG1sJzpcbiAgICAgICAgICByZXNwID0gcmVzcC5yZXNwb25zZVhNTFxuICAgICAgICAgICAgICAmJiByZXNwLnJlc3BvbnNlWE1MLnBhcnNlRXJyb3IgLy8gSUUgdHJvbG9sb1xuICAgICAgICAgICAgICAmJiByZXNwLnJlc3BvbnNlWE1MLnBhcnNlRXJyb3IuZXJyb3JDb2RlXG4gICAgICAgICAgICAgICYmIHJlc3AucmVzcG9uc2VYTUwucGFyc2VFcnJvci5yZWFzb25cbiAgICAgICAgICAgID8gbnVsbFxuICAgICAgICAgICAgOiByZXNwLnJlc3BvbnNlWE1MXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzZWxmLl9yZXNwb25zZUFyZ3MucmVzcCA9IHJlc3BcbiAgICAgIHNlbGYuX2Z1bGZpbGxlZCA9IHRydWVcbiAgICAgIGZuKHJlc3ApXG4gICAgICBzZWxmLl9zdWNjZXNzSGFuZGxlcihyZXNwKVxuICAgICAgd2hpbGUgKHNlbGYuX2Z1bGZpbGxtZW50SGFuZGxlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXNwID0gc2VsZi5fZnVsZmlsbG1lbnRIYW5kbGVycy5zaGlmdCgpKHJlc3ApXG4gICAgICB9XG5cbiAgICAgIGNvbXBsZXRlKHJlc3ApXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdGltZWRPdXQoKSB7XG4gICAgICBzZWxmLl90aW1lZE91dCA9IHRydWVcbiAgICAgIHNlbGYucmVxdWVzdC5hYm9ydCgpICAgICAgXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3IocmVzcCwgbXNnLCB0KSB7XG4gICAgICByZXNwID0gc2VsZi5yZXF1ZXN0XG4gICAgICBzZWxmLl9yZXNwb25zZUFyZ3MucmVzcCA9IHJlc3BcbiAgICAgIHNlbGYuX3Jlc3BvbnNlQXJncy5tc2cgPSBtc2dcbiAgICAgIHNlbGYuX3Jlc3BvbnNlQXJncy50ID0gdFxuICAgICAgc2VsZi5fZXJyZWQgPSB0cnVlXG4gICAgICB3aGlsZSAoc2VsZi5fZXJyb3JIYW5kbGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHNlbGYuX2Vycm9ySGFuZGxlcnMuc2hpZnQoKShyZXNwLCBtc2csIHQpXG4gICAgICB9XG4gICAgICBjb21wbGV0ZShyZXNwKVxuICAgIH1cblxuICAgIHRoaXMucmVxdWVzdCA9IGdldFJlcXVlc3QuY2FsbCh0aGlzLCBzdWNjZXNzLCBlcnJvcilcbiAgfVxuXG4gIFJlcXdlc3QucHJvdG90eXBlID0ge1xuICAgIGFib3J0OiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLl9hYm9ydGVkID0gdHJ1ZVxuICAgICAgdGhpcy5yZXF1ZXN0LmFib3J0KClcbiAgICB9XG5cbiAgLCByZXRyeTogZnVuY3Rpb24gKCkge1xuICAgICAgaW5pdC5jYWxsKHRoaXMsIHRoaXMubywgdGhpcy5mbilcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTbWFsbCBkZXZpYXRpb24gZnJvbSB0aGUgUHJvbWlzZXMgQSBDb21tb25KcyBzcGVjaWZpY2F0aW9uXG4gICAgICogaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvUHJvbWlzZXMvQVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogYHRoZW5gIHdpbGwgZXhlY3V0ZSB1cG9uIHN1Y2Nlc3NmdWwgcmVxdWVzdHNcbiAgICAgKi9cbiAgLCB0aGVuOiBmdW5jdGlvbiAoc3VjY2VzcywgZmFpbCkge1xuICAgICAgc3VjY2VzcyA9IHN1Y2Nlc3MgfHwgZnVuY3Rpb24gKCkge31cbiAgICAgIGZhaWwgPSBmYWlsIHx8IGZ1bmN0aW9uICgpIHt9XG4gICAgICBpZiAodGhpcy5fZnVsZmlsbGVkKSB7XG4gICAgICAgIHRoaXMuX3Jlc3BvbnNlQXJncy5yZXNwID0gc3VjY2Vzcyh0aGlzLl9yZXNwb25zZUFyZ3MucmVzcClcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fZXJyZWQpIHtcbiAgICAgICAgZmFpbCh0aGlzLl9yZXNwb25zZUFyZ3MucmVzcCwgdGhpcy5fcmVzcG9uc2VBcmdzLm1zZywgdGhpcy5fcmVzcG9uc2VBcmdzLnQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9mdWxmaWxsbWVudEhhbmRsZXJzLnB1c2goc3VjY2VzcylcbiAgICAgICAgdGhpcy5fZXJyb3JIYW5kbGVycy5wdXNoKGZhaWwpXG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGBhbHdheXNgIHdpbGwgZXhlY3V0ZSB3aGV0aGVyIHRoZSByZXF1ZXN0IHN1Y2NlZWRzIG9yIGZhaWxzXG4gICAgICovXG4gICwgYWx3YXlzOiBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIGlmICh0aGlzLl9mdWxmaWxsZWQgfHwgdGhpcy5fZXJyZWQpIHtcbiAgICAgICAgZm4odGhpcy5fcmVzcG9uc2VBcmdzLnJlc3ApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9jb21wbGV0ZUhhbmRsZXJzLnB1c2goZm4pXG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGBmYWlsYCB3aWxsIGV4ZWN1dGUgd2hlbiB0aGUgcmVxdWVzdCBmYWlsc1xuICAgICAqL1xuICAsIGZhaWw6IGZ1bmN0aW9uIChmbikge1xuICAgICAgaWYgKHRoaXMuX2VycmVkKSB7XG4gICAgICAgIGZuKHRoaXMuX3Jlc3BvbnNlQXJncy5yZXNwLCB0aGlzLl9yZXNwb25zZUFyZ3MubXNnLCB0aGlzLl9yZXNwb25zZUFyZ3MudClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2Vycm9ySGFuZGxlcnMucHVzaChmbilcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuICAsICdjYXRjaCc6IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIHRoaXMuZmFpbChmbilcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZXF3ZXN0KG8sIGZuKSB7XG4gICAgcmV0dXJuIG5ldyBSZXF3ZXN0KG8sIGZuKVxuICB9XG5cbiAgLy8gbm9ybWFsaXplIG5ld2xpbmUgdmFyaWFudHMgYWNjb3JkaW5nIHRvIHNwZWMgLT4gQ1JMRlxuICBmdW5jdGlvbiBub3JtYWxpemUocykge1xuICAgIHJldHVybiBzID8gcy5yZXBsYWNlKC9cXHI/XFxuL2csICdcXHJcXG4nKSA6ICcnXG4gIH1cblxuICBmdW5jdGlvbiBzZXJpYWwoZWwsIGNiKSB7XG4gICAgdmFyIG4gPSBlbC5uYW1lXG4gICAgICAsIHQgPSBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgICwgb3B0Q2IgPSBmdW5jdGlvbiAobykge1xuICAgICAgICAgIC8vIElFIGdpdmVzIHZhbHVlPVwiXCIgZXZlbiB3aGVyZSB0aGVyZSBpcyBubyB2YWx1ZSBhdHRyaWJ1dGVcbiAgICAgICAgICAvLyAnc3BlY2lmaWVkJyByZWY6IGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvY29yZS5odG1sI0lELTg2MjUyOTI3M1xuICAgICAgICAgIGlmIChvICYmICFvWydkaXNhYmxlZCddKVxuICAgICAgICAgICAgY2Iobiwgbm9ybWFsaXplKG9bJ2F0dHJpYnV0ZXMnXVsndmFsdWUnXSAmJiBvWydhdHRyaWJ1dGVzJ11bJ3ZhbHVlJ11bJ3NwZWNpZmllZCddID8gb1sndmFsdWUnXSA6IG9bJ3RleHQnXSkpXG4gICAgICAgIH1cbiAgICAgICwgY2gsIHJhLCB2YWwsIGlcblxuICAgIC8vIGRvbid0IHNlcmlhbGl6ZSBlbGVtZW50cyB0aGF0IGFyZSBkaXNhYmxlZCBvciB3aXRob3V0IGEgbmFtZVxuICAgIGlmIChlbC5kaXNhYmxlZCB8fCAhbikgcmV0dXJuXG5cbiAgICBzd2l0Y2ggKHQpIHtcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgICBpZiAoIS9yZXNldHxidXR0b258aW1hZ2V8ZmlsZS9pLnRlc3QoZWwudHlwZSkpIHtcbiAgICAgICAgY2ggPSAvY2hlY2tib3gvaS50ZXN0KGVsLnR5cGUpXG4gICAgICAgIHJhID0gL3JhZGlvL2kudGVzdChlbC50eXBlKVxuICAgICAgICB2YWwgPSBlbC52YWx1ZVxuICAgICAgICAvLyBXZWJLaXQgZ2l2ZXMgdXMgXCJcIiBpbnN0ZWFkIG9mIFwib25cIiBpZiBhIGNoZWNrYm94IGhhcyBubyB2YWx1ZSwgc28gY29ycmVjdCBpdCBoZXJlXG4gICAgICAgIDsoIShjaCB8fCByYSkgfHwgZWwuY2hlY2tlZCkgJiYgY2Iobiwgbm9ybWFsaXplKGNoICYmIHZhbCA9PT0gJycgPyAnb24nIDogdmFsKSlcbiAgICAgIH1cbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgY2Iobiwgbm9ybWFsaXplKGVsLnZhbHVlKSlcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgIGlmIChlbC50eXBlLnRvTG93ZXJDYXNlKCkgPT09ICdzZWxlY3Qtb25lJykge1xuICAgICAgICBvcHRDYihlbC5zZWxlY3RlZEluZGV4ID49IDAgPyBlbC5vcHRpb25zW2VsLnNlbGVjdGVkSW5kZXhdIDogbnVsbClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGVsLmxlbmd0aCAmJiBpIDwgZWwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBlbC5vcHRpb25zW2ldLnNlbGVjdGVkICYmIG9wdENiKGVsLm9wdGlvbnNbaV0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgLy8gY29sbGVjdCB1cCBhbGwgZm9ybSBlbGVtZW50cyBmb3VuZCBmcm9tIHRoZSBwYXNzZWQgYXJndW1lbnQgZWxlbWVudHMgYWxsXG4gIC8vIHRoZSB3YXkgZG93biB0byBjaGlsZCBlbGVtZW50czsgcGFzcyBhICc8Zm9ybT4nIG9yIGZvcm0gZmllbGRzLlxuICAvLyBjYWxsZWQgd2l0aCAndGhpcyc9Y2FsbGJhY2sgdG8gdXNlIGZvciBzZXJpYWwoKSBvbiBlYWNoIGVsZW1lbnRcbiAgZnVuY3Rpb24gZWFjaEZvcm1FbGVtZW50KCkge1xuICAgIHZhciBjYiA9IHRoaXNcbiAgICAgICwgZSwgaVxuICAgICAgLCBzZXJpYWxpemVTdWJ0YWdzID0gZnVuY3Rpb24gKGUsIHRhZ3MpIHtcbiAgICAgICAgICB2YXIgaSwgaiwgZmFcbiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGFncy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZmEgPSBlW2J5VGFnXSh0YWdzW2ldKVxuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGZhLmxlbmd0aDsgaisrKSBzZXJpYWwoZmFbal0sIGNiKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgZSA9IGFyZ3VtZW50c1tpXVxuICAgICAgaWYgKC9pbnB1dHxzZWxlY3R8dGV4dGFyZWEvaS50ZXN0KGUudGFnTmFtZSkpIHNlcmlhbChlLCBjYilcbiAgICAgIHNlcmlhbGl6ZVN1YnRhZ3MoZSwgWyAnaW5wdXQnLCAnc2VsZWN0JywgJ3RleHRhcmVhJyBdKVxuICAgIH1cbiAgfVxuXG4gIC8vIHN0YW5kYXJkIHF1ZXJ5IHN0cmluZyBzdHlsZSBzZXJpYWxpemF0aW9uXG4gIGZ1bmN0aW9uIHNlcmlhbGl6ZVF1ZXJ5U3RyaW5nKCkge1xuICAgIHJldHVybiByZXF3ZXN0LnRvUXVlcnlTdHJpbmcocmVxd2VzdC5zZXJpYWxpemVBcnJheS5hcHBseShudWxsLCBhcmd1bWVudHMpKVxuICB9XG5cbiAgLy8geyAnbmFtZSc6ICd2YWx1ZScsIC4uLiB9IHN0eWxlIHNlcmlhbGl6YXRpb25cbiAgZnVuY3Rpb24gc2VyaWFsaXplSGFzaCgpIHtcbiAgICB2YXIgaGFzaCA9IHt9XG4gICAgZWFjaEZvcm1FbGVtZW50LmFwcGx5KGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgICAgaWYgKG5hbWUgaW4gaGFzaCkge1xuICAgICAgICBoYXNoW25hbWVdICYmICFpc0FycmF5KGhhc2hbbmFtZV0pICYmIChoYXNoW25hbWVdID0gW2hhc2hbbmFtZV1dKVxuICAgICAgICBoYXNoW25hbWVdLnB1c2godmFsdWUpXG4gICAgICB9IGVsc2UgaGFzaFtuYW1lXSA9IHZhbHVlXG4gICAgfSwgYXJndW1lbnRzKVxuICAgIHJldHVybiBoYXNoXG4gIH1cblxuICAvLyBbIHsgbmFtZTogJ25hbWUnLCB2YWx1ZTogJ3ZhbHVlJyB9LCAuLi4gXSBzdHlsZSBzZXJpYWxpemF0aW9uXG4gIHJlcXdlc3Quc2VyaWFsaXplQXJyYXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyciA9IFtdXG4gICAgZWFjaEZvcm1FbGVtZW50LmFwcGx5KGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgICAgYXJyLnB1c2goe25hbWU6IG5hbWUsIHZhbHVlOiB2YWx1ZX0pXG4gICAgfSwgYXJndW1lbnRzKVxuICAgIHJldHVybiBhcnJcbiAgfVxuXG4gIHJlcXdlc3Quc2VyaWFsaXplID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgICB2YXIgb3B0LCBmblxuICAgICAgLCBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKVxuXG4gICAgb3B0ID0gYXJncy5wb3AoKVxuICAgIG9wdCAmJiBvcHQubm9kZVR5cGUgJiYgYXJncy5wdXNoKG9wdCkgJiYgKG9wdCA9IG51bGwpXG4gICAgb3B0ICYmIChvcHQgPSBvcHQudHlwZSlcblxuICAgIGlmIChvcHQgPT0gJ21hcCcpIGZuID0gc2VyaWFsaXplSGFzaFxuICAgIGVsc2UgaWYgKG9wdCA9PSAnYXJyYXknKSBmbiA9IHJlcXdlc3Quc2VyaWFsaXplQXJyYXlcbiAgICBlbHNlIGZuID0gc2VyaWFsaXplUXVlcnlTdHJpbmdcblxuICAgIHJldHVybiBmbi5hcHBseShudWxsLCBhcmdzKVxuICB9XG5cbiAgcmVxd2VzdC50b1F1ZXJ5U3RyaW5nID0gZnVuY3Rpb24gKG8sIHRyYWQpIHtcbiAgICB2YXIgcHJlZml4LCBpXG4gICAgICAsIHRyYWRpdGlvbmFsID0gdHJhZCB8fCBmYWxzZVxuICAgICAgLCBzID0gW11cbiAgICAgICwgZW5jID0gZW5jb2RlVVJJQ29tcG9uZW50XG4gICAgICAsIGFkZCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgICAgLy8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCByZXR1cm4gaXRzIHZhbHVlXG4gICAgICAgICAgdmFsdWUgPSAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIHZhbHVlKSA/IHZhbHVlKCkgOiAodmFsdWUgPT0gbnVsbCA/ICcnIDogdmFsdWUpXG4gICAgICAgICAgc1tzLmxlbmd0aF0gPSBlbmMoa2V5KSArICc9JyArIGVuYyh2YWx1ZSlcbiAgICAgICAgfVxuICAgIC8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuXG4gICAgaWYgKGlzQXJyYXkobykpIHtcbiAgICAgIGZvciAoaSA9IDA7IG8gJiYgaSA8IG8ubGVuZ3RoOyBpKyspIGFkZChvW2ldWyduYW1lJ10sIG9baV1bJ3ZhbHVlJ10pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRyYWRpdGlvbmFsLCBlbmNvZGUgdGhlIFwib2xkXCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyXG4gICAgICAvLyBkaWQgaXQpLCBvdGhlcndpc2UgZW5jb2RlIHBhcmFtcyByZWN1cnNpdmVseS5cbiAgICAgIGZvciAocHJlZml4IGluIG8pIHtcbiAgICAgICAgaWYgKG8uaGFzT3duUHJvcGVydHkocHJlZml4KSkgYnVpbGRQYXJhbXMocHJlZml4LCBvW3ByZWZpeF0sIHRyYWRpdGlvbmFsLCBhZGQpXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc3BhY2VzIHNob3VsZCBiZSArIGFjY29yZGluZyB0byBzcGVjXG4gICAgcmV0dXJuIHMuam9pbignJicpLnJlcGxhY2UoLyUyMC9nLCAnKycpXG4gIH1cblxuICBmdW5jdGlvbiBidWlsZFBhcmFtcyhwcmVmaXgsIG9iaiwgdHJhZGl0aW9uYWwsIGFkZCkge1xuICAgIHZhciBuYW1lLCBpLCB2XG4gICAgICAsIHJicmFja2V0ID0gL1xcW1xcXSQvXG5cbiAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAvLyBTZXJpYWxpemUgYXJyYXkgaXRlbS5cbiAgICAgIGZvciAoaSA9IDA7IG9iaiAmJiBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHYgPSBvYmpbaV1cbiAgICAgICAgaWYgKHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QocHJlZml4KSkge1xuICAgICAgICAgIC8vIFRyZWF0IGVhY2ggYXJyYXkgaXRlbSBhcyBhIHNjYWxhci5cbiAgICAgICAgICBhZGQocHJlZml4LCB2KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJ1aWxkUGFyYW1zKHByZWZpeCArICdbJyArICh0eXBlb2YgdiA9PT0gJ29iamVjdCcgPyBpIDogJycpICsgJ10nLCB2LCB0cmFkaXRpb25hbCwgYWRkKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvYmogJiYgb2JqLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICAvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXG4gICAgICBmb3IgKG5hbWUgaW4gb2JqKSB7XG4gICAgICAgIGJ1aWxkUGFyYW1zKHByZWZpeCArICdbJyArIG5hbWUgKyAnXScsIG9ialtuYW1lXSwgdHJhZGl0aW9uYWwsIGFkZClcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTZXJpYWxpemUgc2NhbGFyIGl0ZW0uXG4gICAgICBhZGQocHJlZml4LCBvYmopXG4gICAgfVxuICB9XG5cbiAgcmVxd2VzdC5nZXRjYWxsYmFja1ByZWZpeCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2tQcmVmaXhcbiAgfVxuXG4gIC8vIGpRdWVyeSBhbmQgWmVwdG8gY29tcGF0aWJpbGl0eSwgZGlmZmVyZW5jZXMgY2FuIGJlIHJlbWFwcGVkIGhlcmUgc28geW91IGNhbiBjYWxsXG4gIC8vIC5hamF4LmNvbXBhdChvcHRpb25zLCBjYWxsYmFjaylcbiAgcmVxd2VzdC5jb21wYXQgPSBmdW5jdGlvbiAobywgZm4pIHtcbiAgICBpZiAobykge1xuICAgICAgb1sndHlwZSddICYmIChvWydtZXRob2QnXSA9IG9bJ3R5cGUnXSkgJiYgZGVsZXRlIG9bJ3R5cGUnXVxuICAgICAgb1snZGF0YVR5cGUnXSAmJiAob1sndHlwZSddID0gb1snZGF0YVR5cGUnXSlcbiAgICAgIG9bJ2pzb25wQ2FsbGJhY2snXSAmJiAob1snanNvbnBDYWxsYmFja05hbWUnXSA9IG9bJ2pzb25wQ2FsbGJhY2snXSkgJiYgZGVsZXRlIG9bJ2pzb25wQ2FsbGJhY2snXVxuICAgICAgb1snanNvbnAnXSAmJiAob1snanNvbnBDYWxsYmFjayddID0gb1snanNvbnAnXSlcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBSZXF3ZXN0KG8sIGZuKVxuICB9XG5cbiAgcmVxd2VzdC5hamF4U2V0dXAgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gICAgZm9yICh2YXIgayBpbiBvcHRpb25zKSB7XG4gICAgICBnbG9iYWxTZXR1cE9wdGlvbnNba10gPSBvcHRpb25zW2tdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcXdlc3Rcbn0pO1xuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTEtMjAxNCBGZWxpeCBHbmFzc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKi9cbihmdW5jdGlvbihyb290LCBmYWN0b3J5KSB7XG5cbiAgLyogQ29tbW9uSlMgKi9cbiAgaWYgKHR5cGVvZiBleHBvcnRzID09ICdvYmplY3QnKSAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KClcblxuICAvKiBBTUQgbW9kdWxlICovXG4gIGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSBkZWZpbmUoZmFjdG9yeSlcblxuICAvKiBCcm93c2VyIGdsb2JhbCAqL1xuICBlbHNlIHJvb3QuU3Bpbm5lciA9IGZhY3RvcnkoKVxufVxuKHRoaXMsIGZ1bmN0aW9uKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgcHJlZml4ZXMgPSBbJ3dlYmtpdCcsICdNb3onLCAnbXMnLCAnTyddIC8qIFZlbmRvciBwcmVmaXhlcyAqL1xuICAgICwgYW5pbWF0aW9ucyA9IHt9IC8qIEFuaW1hdGlvbiBydWxlcyBrZXllZCBieSB0aGVpciBuYW1lICovXG4gICAgLCB1c2VDc3NBbmltYXRpb25zIC8qIFdoZXRoZXIgdG8gdXNlIENTUyBhbmltYXRpb25zIG9yIHNldFRpbWVvdXQgKi9cblxuICAvKipcbiAgICogVXRpbGl0eSBmdW5jdGlvbiB0byBjcmVhdGUgZWxlbWVudHMuIElmIG5vIHRhZyBuYW1lIGlzIGdpdmVuLFxuICAgKiBhIERJViBpcyBjcmVhdGVkLiBPcHRpb25hbGx5IHByb3BlcnRpZXMgY2FuIGJlIHBhc3NlZC5cbiAgICovXG4gIGZ1bmN0aW9uIGNyZWF0ZUVsKHRhZywgcHJvcCkge1xuICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnIHx8ICdkaXYnKVxuICAgICAgLCBuXG5cbiAgICBmb3IobiBpbiBwcm9wKSBlbFtuXSA9IHByb3Bbbl1cbiAgICByZXR1cm4gZWxcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmRzIGNoaWxkcmVuIGFuZCByZXR1cm5zIHRoZSBwYXJlbnQuXG4gICAqL1xuICBmdW5jdGlvbiBpbnMocGFyZW50IC8qIGNoaWxkMSwgY2hpbGQyLCAuLi4qLykge1xuICAgIGZvciAodmFyIGk9MSwgbj1hcmd1bWVudHMubGVuZ3RoOyBpPG47IGkrKylcbiAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChhcmd1bWVudHNbaV0pXG5cbiAgICByZXR1cm4gcGFyZW50XG4gIH1cblxuICAvKipcbiAgICogSW5zZXJ0IGEgbmV3IHN0eWxlc2hlZXQgdG8gaG9sZCB0aGUgQGtleWZyYW1lIG9yIFZNTCBydWxlcy5cbiAgICovXG4gIHZhciBzaGVldCA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZWwgPSBjcmVhdGVFbCgnc3R5bGUnLCB7dHlwZSA6ICd0ZXh0L2Nzcyd9KVxuICAgIGlucyhkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLCBlbClcbiAgICByZXR1cm4gZWwuc2hlZXQgfHwgZWwuc3R5bGVTaGVldFxuICB9KCkpXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gb3BhY2l0eSBrZXlmcmFtZSBhbmltYXRpb24gcnVsZSBhbmQgcmV0dXJucyBpdHMgbmFtZS5cbiAgICogU2luY2UgbW9zdCBtb2JpbGUgV2Via2l0cyBoYXZlIHRpbWluZyBpc3N1ZXMgd2l0aCBhbmltYXRpb24tZGVsYXksXG4gICAqIHdlIGNyZWF0ZSBzZXBhcmF0ZSBydWxlcyBmb3IgZWFjaCBsaW5lL3NlZ21lbnQuXG4gICAqL1xuICBmdW5jdGlvbiBhZGRBbmltYXRpb24oYWxwaGEsIHRyYWlsLCBpLCBsaW5lcykge1xuICAgIHZhciBuYW1lID0gWydvcGFjaXR5JywgdHJhaWwsIH5+KGFscGhhKjEwMCksIGksIGxpbmVzXS5qb2luKCctJylcbiAgICAgICwgc3RhcnQgPSAwLjAxICsgaS9saW5lcyAqIDEwMFxuICAgICAgLCB6ID0gTWF0aC5tYXgoMSAtICgxLWFscGhhKSAvIHRyYWlsICogKDEwMC1zdGFydCksIGFscGhhKVxuICAgICAgLCBwcmVmaXggPSB1c2VDc3NBbmltYXRpb25zLnN1YnN0cmluZygwLCB1c2VDc3NBbmltYXRpb25zLmluZGV4T2YoJ0FuaW1hdGlvbicpKS50b0xvd2VyQ2FzZSgpXG4gICAgICAsIHByZSA9IHByZWZpeCAmJiAnLScgKyBwcmVmaXggKyAnLScgfHwgJydcblxuICAgIGlmICghYW5pbWF0aW9uc1tuYW1lXSkge1xuICAgICAgc2hlZXQuaW5zZXJ0UnVsZShcbiAgICAgICAgJ0AnICsgcHJlICsgJ2tleWZyYW1lcyAnICsgbmFtZSArICd7JyArXG4gICAgICAgICcwJXtvcGFjaXR5OicgKyB6ICsgJ30nICtcbiAgICAgICAgc3RhcnQgKyAnJXtvcGFjaXR5OicgKyBhbHBoYSArICd9JyArXG4gICAgICAgIChzdGFydCswLjAxKSArICcle29wYWNpdHk6MX0nICtcbiAgICAgICAgKHN0YXJ0K3RyYWlsKSAlIDEwMCArICcle29wYWNpdHk6JyArIGFscGhhICsgJ30nICtcbiAgICAgICAgJzEwMCV7b3BhY2l0eTonICsgeiArICd9JyArXG4gICAgICAgICd9Jywgc2hlZXQuY3NzUnVsZXMubGVuZ3RoKVxuXG4gICAgICBhbmltYXRpb25zW25hbWVdID0gMVxuICAgIH1cblxuICAgIHJldHVybiBuYW1lXG4gIH1cblxuICAvKipcbiAgICogVHJpZXMgdmFyaW91cyB2ZW5kb3IgcHJlZml4ZXMgYW5kIHJldHVybnMgdGhlIGZpcnN0IHN1cHBvcnRlZCBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIHZlbmRvcihlbCwgcHJvcCkge1xuICAgIHZhciBzID0gZWwuc3R5bGVcbiAgICAgICwgcHBcbiAgICAgICwgaVxuXG4gICAgcHJvcCA9IHByb3AuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBwcm9wLnNsaWNlKDEpXG4gICAgZm9yKGk9MDsgaTxwcmVmaXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgcHAgPSBwcmVmaXhlc1tpXStwcm9wXG4gICAgICBpZihzW3BwXSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcHBcbiAgICB9XG4gICAgaWYoc1twcm9wXSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcHJvcFxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgbXVsdGlwbGUgc3R5bGUgcHJvcGVydGllcyBhdCBvbmNlLlxuICAgKi9cbiAgZnVuY3Rpb24gY3NzKGVsLCBwcm9wKSB7XG4gICAgZm9yICh2YXIgbiBpbiBwcm9wKVxuICAgICAgZWwuc3R5bGVbdmVuZG9yKGVsLCBuKXx8bl0gPSBwcm9wW25dXG5cbiAgICByZXR1cm4gZWxcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWxscyBpbiBkZWZhdWx0IHZhbHVlcy5cbiAgICovXG4gIGZ1bmN0aW9uIG1lcmdlKG9iaikge1xuICAgIGZvciAodmFyIGk9MTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGRlZiA9IGFyZ3VtZW50c1tpXVxuICAgICAgZm9yICh2YXIgbiBpbiBkZWYpXG4gICAgICAgIGlmIChvYmpbbl0gPT09IHVuZGVmaW5lZCkgb2JqW25dID0gZGVmW25dXG4gICAgfVxuICAgIHJldHVybiBvYmpcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBsaW5lIGNvbG9yIGZyb20gdGhlIGdpdmVuIHN0cmluZyBvciBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGdldENvbG9yKGNvbG9yLCBpZHgpIHtcbiAgICByZXR1cm4gdHlwZW9mIGNvbG9yID09ICdzdHJpbmcnID8gY29sb3IgOiBjb2xvcltpZHggJSBjb2xvci5sZW5ndGhdXG4gIH1cblxuICAvLyBCdWlsdC1pbiBkZWZhdWx0c1xuXG4gIHZhciBkZWZhdWx0cyA9IHtcbiAgICBsaW5lczogMTIsICAgICAgICAgICAgLy8gVGhlIG51bWJlciBvZiBsaW5lcyB0byBkcmF3XG4gICAgbGVuZ3RoOiA3LCAgICAgICAgICAgIC8vIFRoZSBsZW5ndGggb2YgZWFjaCBsaW5lXG4gICAgd2lkdGg6IDUsICAgICAgICAgICAgIC8vIFRoZSBsaW5lIHRoaWNrbmVzc1xuICAgIHJhZGl1czogMTAsICAgICAgICAgICAvLyBUaGUgcmFkaXVzIG9mIHRoZSBpbm5lciBjaXJjbGVcbiAgICByb3RhdGU6IDAsICAgICAgICAgICAgLy8gUm90YXRpb24gb2Zmc2V0XG4gICAgY29ybmVyczogMSwgICAgICAgICAgIC8vIFJvdW5kbmVzcyAoMC4uMSlcbiAgICBjb2xvcjogJyMwMDAnLCAgICAgICAgLy8gI3JnYiBvciAjcnJnZ2JiXG4gICAgZGlyZWN0aW9uOiAxLCAgICAgICAgIC8vIDE6IGNsb2Nrd2lzZSwgLTE6IGNvdW50ZXJjbG9ja3dpc2VcbiAgICBzcGVlZDogMSwgICAgICAgICAgICAgLy8gUm91bmRzIHBlciBzZWNvbmRcbiAgICB0cmFpbDogMTAwLCAgICAgICAgICAgLy8gQWZ0ZXJnbG93IHBlcmNlbnRhZ2VcbiAgICBvcGFjaXR5OiAxLzQsICAgICAgICAgLy8gT3BhY2l0eSBvZiB0aGUgbGluZXNcbiAgICBmcHM6IDIwLCAgICAgICAgICAgICAgLy8gRnJhbWVzIHBlciBzZWNvbmQgd2hlbiB1c2luZyBzZXRUaW1lb3V0KClcbiAgICB6SW5kZXg6IDJlOSwgICAgICAgICAgLy8gVXNlIGEgaGlnaCB6LWluZGV4IGJ5IGRlZmF1bHRcbiAgICBjbGFzc05hbWU6ICdzcGlubmVyJywgLy8gQ1NTIGNsYXNzIHRvIGFzc2lnbiB0byB0aGUgZWxlbWVudFxuICAgIHRvcDogJzUwJScsICAgICAgICAgICAvLyBjZW50ZXIgdmVydGljYWxseVxuICAgIGxlZnQ6ICc1MCUnLCAgICAgICAgICAvLyBjZW50ZXIgaG9yaXpvbnRhbGx5XG4gICAgcG9zaXRpb246ICdhYnNvbHV0ZScgIC8vIGVsZW1lbnQgcG9zaXRpb25cbiAgfVxuXG4gIC8qKiBUaGUgY29uc3RydWN0b3IgKi9cbiAgZnVuY3Rpb24gU3Bpbm5lcihvKSB7XG4gICAgdGhpcy5vcHRzID0gbWVyZ2UobyB8fCB7fSwgU3Bpbm5lci5kZWZhdWx0cywgZGVmYXVsdHMpXG4gIH1cblxuICAvLyBHbG9iYWwgZGVmYXVsdHMgdGhhdCBvdmVycmlkZSB0aGUgYnVpbHQtaW5zOlxuICBTcGlubmVyLmRlZmF1bHRzID0ge31cblxuICBtZXJnZShTcGlubmVyLnByb3RvdHlwZSwge1xuXG4gICAgLyoqXG4gICAgICogQWRkcyB0aGUgc3Bpbm5lciB0byB0aGUgZ2l2ZW4gdGFyZ2V0IGVsZW1lbnQuIElmIHRoaXMgaW5zdGFuY2UgaXMgYWxyZWFkeVxuICAgICAqIHNwaW5uaW5nLCBpdCBpcyBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgZnJvbSBpdHMgcHJldmlvdXMgdGFyZ2V0IGIgY2FsbGluZ1xuICAgICAqIHN0b3AoKSBpbnRlcm5hbGx5LlxuICAgICAqL1xuICAgIHNwaW46IGZ1bmN0aW9uKHRhcmdldCkge1xuICAgICAgdGhpcy5zdG9wKClcblxuICAgICAgdmFyIHNlbGYgPSB0aGlzXG4gICAgICAgICwgbyA9IHNlbGYub3B0c1xuICAgICAgICAsIGVsID0gc2VsZi5lbCA9IGNzcyhjcmVhdGVFbCgwLCB7Y2xhc3NOYW1lOiBvLmNsYXNzTmFtZX0pLCB7cG9zaXRpb246IG8ucG9zaXRpb24sIHdpZHRoOiAwLCB6SW5kZXg6IG8uekluZGV4fSlcblxuICAgICAgY3NzKGVsLCB7XG4gICAgICAgIGxlZnQ6IG8ubGVmdCxcbiAgICAgICAgdG9wOiBvLnRvcFxuICAgICAgfSlcbiAgICAgICAgXG4gICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIHRhcmdldC5pbnNlcnRCZWZvcmUoZWwsIHRhcmdldC5maXJzdENoaWxkfHxudWxsKVxuICAgICAgfVxuXG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAncHJvZ3Jlc3NiYXInKVxuICAgICAgc2VsZi5saW5lcyhlbCwgc2VsZi5vcHRzKVxuXG4gICAgICBpZiAoIXVzZUNzc0FuaW1hdGlvbnMpIHtcbiAgICAgICAgLy8gTm8gQ1NTIGFuaW1hdGlvbiBzdXBwb3J0LCB1c2Ugc2V0VGltZW91dCgpIGluc3RlYWRcbiAgICAgICAgdmFyIGkgPSAwXG4gICAgICAgICAgLCBzdGFydCA9IChvLmxpbmVzIC0gMSkgKiAoMSAtIG8uZGlyZWN0aW9uKSAvIDJcbiAgICAgICAgICAsIGFscGhhXG4gICAgICAgICAgLCBmcHMgPSBvLmZwc1xuICAgICAgICAgICwgZiA9IGZwcy9vLnNwZWVkXG4gICAgICAgICAgLCBvc3RlcCA9ICgxLW8ub3BhY2l0eSkgLyAoZipvLnRyYWlsIC8gMTAwKVxuICAgICAgICAgICwgYXN0ZXAgPSBmL28ubGluZXNcblxuICAgICAgICA7KGZ1bmN0aW9uIGFuaW0oKSB7XG4gICAgICAgICAgaSsrO1xuICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgby5saW5lczsgaisrKSB7XG4gICAgICAgICAgICBhbHBoYSA9IE1hdGgubWF4KDEgLSAoaSArIChvLmxpbmVzIC0gaikgKiBhc3RlcCkgJSBmICogb3N0ZXAsIG8ub3BhY2l0eSlcblxuICAgICAgICAgICAgc2VsZi5vcGFjaXR5KGVsLCBqICogby5kaXJlY3Rpb24gKyBzdGFydCwgYWxwaGEsIG8pXG4gICAgICAgICAgfVxuICAgICAgICAgIHNlbGYudGltZW91dCA9IHNlbGYuZWwgJiYgc2V0VGltZW91dChhbmltLCB+figxMDAwL2ZwcykpXG4gICAgICAgIH0pKClcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZWxmXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFN0b3BzIGFuZCByZW1vdmVzIHRoZSBTcGlubmVyLlxuICAgICAqL1xuICAgIHN0b3A6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVsID0gdGhpcy5lbFxuICAgICAgaWYgKGVsKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpXG4gICAgICAgIGlmIChlbC5wYXJlbnROb2RlKSBlbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsKVxuICAgICAgICB0aGlzLmVsID0gdW5kZWZpbmVkXG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpc1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBtZXRob2QgdGhhdCBkcmF3cyB0aGUgaW5kaXZpZHVhbCBsaW5lcy4gV2lsbCBiZSBvdmVyd3JpdHRlblxuICAgICAqIGluIFZNTCBmYWxsYmFjayBtb2RlIGJlbG93LlxuICAgICAqL1xuICAgIGxpbmVzOiBmdW5jdGlvbihlbCwgbykge1xuICAgICAgdmFyIGkgPSAwXG4gICAgICAgICwgc3RhcnQgPSAoby5saW5lcyAtIDEpICogKDEgLSBvLmRpcmVjdGlvbikgLyAyXG4gICAgICAgICwgc2VnXG5cbiAgICAgIGZ1bmN0aW9uIGZpbGwoY29sb3IsIHNoYWRvdykge1xuICAgICAgICByZXR1cm4gY3NzKGNyZWF0ZUVsKCksIHtcbiAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICB3aWR0aDogKG8ubGVuZ3RoK28ud2lkdGgpICsgJ3B4JyxcbiAgICAgICAgICBoZWlnaHQ6IG8ud2lkdGggKyAncHgnLFxuICAgICAgICAgIGJhY2tncm91bmQ6IGNvbG9yLFxuICAgICAgICAgIGJveFNoYWRvdzogc2hhZG93LFxuICAgICAgICAgIHRyYW5zZm9ybU9yaWdpbjogJ2xlZnQnLFxuICAgICAgICAgIHRyYW5zZm9ybTogJ3JvdGF0ZSgnICsgfn4oMzYwL28ubGluZXMqaStvLnJvdGF0ZSkgKyAnZGVnKSB0cmFuc2xhdGUoJyArIG8ucmFkaXVzKydweCcgKycsMCknLFxuICAgICAgICAgIGJvcmRlclJhZGl1czogKG8uY29ybmVycyAqIG8ud2lkdGg+PjEpICsgJ3B4J1xuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBmb3IgKDsgaSA8IG8ubGluZXM7IGkrKykge1xuICAgICAgICBzZWcgPSBjc3MoY3JlYXRlRWwoKSwge1xuICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgIHRvcDogMSt+KG8ud2lkdGgvMikgKyAncHgnLFxuICAgICAgICAgIHRyYW5zZm9ybTogby5od2FjY2VsID8gJ3RyYW5zbGF0ZTNkKDAsMCwwKScgOiAnJyxcbiAgICAgICAgICBvcGFjaXR5OiBvLm9wYWNpdHksXG4gICAgICAgICAgYW5pbWF0aW9uOiB1c2VDc3NBbmltYXRpb25zICYmIGFkZEFuaW1hdGlvbihvLm9wYWNpdHksIG8udHJhaWwsIHN0YXJ0ICsgaSAqIG8uZGlyZWN0aW9uLCBvLmxpbmVzKSArICcgJyArIDEvby5zcGVlZCArICdzIGxpbmVhciBpbmZpbml0ZSdcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAoby5zaGFkb3cpIGlucyhzZWcsIGNzcyhmaWxsKCcjMDAwJywgJzAgMCA0cHggJyArICcjMDAwJyksIHt0b3A6IDIrJ3B4J30pKVxuICAgICAgICBpbnMoZWwsIGlucyhzZWcsIGZpbGwoZ2V0Q29sb3Ioby5jb2xvciwgaSksICcwIDAgMXB4IHJnYmEoMCwwLDAsLjEpJykpKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGVsXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB0aGF0IGFkanVzdHMgdGhlIG9wYWNpdHkgb2YgYSBzaW5nbGUgbGluZS5cbiAgICAgKiBXaWxsIGJlIG92ZXJ3cml0dGVuIGluIFZNTCBmYWxsYmFjayBtb2RlIGJlbG93LlxuICAgICAqL1xuICAgIG9wYWNpdHk6IGZ1bmN0aW9uKGVsLCBpLCB2YWwpIHtcbiAgICAgIGlmIChpIDwgZWwuY2hpbGROb2Rlcy5sZW5ndGgpIGVsLmNoaWxkTm9kZXNbaV0uc3R5bGUub3BhY2l0eSA9IHZhbFxuICAgIH1cblxuICB9KVxuXG5cbiAgZnVuY3Rpb24gaW5pdFZNTCgpIHtcblxuICAgIC8qIFV0aWxpdHkgZnVuY3Rpb24gdG8gY3JlYXRlIGEgVk1MIHRhZyAqL1xuICAgIGZ1bmN0aW9uIHZtbCh0YWcsIGF0dHIpIHtcbiAgICAgIHJldHVybiBjcmVhdGVFbCgnPCcgKyB0YWcgKyAnIHhtbG5zPVwidXJuOnNjaGVtYXMtbWljcm9zb2Z0LmNvbTp2bWxcIiBjbGFzcz1cInNwaW4tdm1sXCI+JywgYXR0cilcbiAgICB9XG5cbiAgICAvLyBObyBDU1MgdHJhbnNmb3JtcyBidXQgVk1MIHN1cHBvcnQsIGFkZCBhIENTUyBydWxlIGZvciBWTUwgZWxlbWVudHM6XG4gICAgc2hlZXQuYWRkUnVsZSgnLnNwaW4tdm1sJywgJ2JlaGF2aW9yOnVybCgjZGVmYXVsdCNWTUwpJylcblxuICAgIFNwaW5uZXIucHJvdG90eXBlLmxpbmVzID0gZnVuY3Rpb24oZWwsIG8pIHtcbiAgICAgIHZhciByID0gby5sZW5ndGgrby53aWR0aFxuICAgICAgICAsIHMgPSAyKnJcblxuICAgICAgZnVuY3Rpb24gZ3JwKCkge1xuICAgICAgICByZXR1cm4gY3NzKFxuICAgICAgICAgIHZtbCgnZ3JvdXAnLCB7XG4gICAgICAgICAgICBjb29yZHNpemU6IHMgKyAnICcgKyBzLFxuICAgICAgICAgICAgY29vcmRvcmlnaW46IC1yICsgJyAnICsgLXJcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7IHdpZHRoOiBzLCBoZWlnaHQ6IHMgfVxuICAgICAgICApXG4gICAgICB9XG5cbiAgICAgIHZhciBtYXJnaW4gPSAtKG8ud2lkdGgrby5sZW5ndGgpKjIgKyAncHgnXG4gICAgICAgICwgZyA9IGNzcyhncnAoKSwge3Bvc2l0aW9uOiAnYWJzb2x1dGUnLCB0b3A6IG1hcmdpbiwgbGVmdDogbWFyZ2lufSlcbiAgICAgICAgLCBpXG5cbiAgICAgIGZ1bmN0aW9uIHNlZyhpLCBkeCwgZmlsdGVyKSB7XG4gICAgICAgIGlucyhnLFxuICAgICAgICAgIGlucyhjc3MoZ3JwKCksIHtyb3RhdGlvbjogMzYwIC8gby5saW5lcyAqIGkgKyAnZGVnJywgbGVmdDogfn5keH0pLFxuICAgICAgICAgICAgaW5zKGNzcyh2bWwoJ3JvdW5kcmVjdCcsIHthcmNzaXplOiBvLmNvcm5lcnN9KSwge1xuICAgICAgICAgICAgICAgIHdpZHRoOiByLFxuICAgICAgICAgICAgICAgIGhlaWdodDogby53aWR0aCxcbiAgICAgICAgICAgICAgICBsZWZ0OiBvLnJhZGl1cyxcbiAgICAgICAgICAgICAgICB0b3A6IC1vLndpZHRoPj4xLFxuICAgICAgICAgICAgICAgIGZpbHRlcjogZmlsdGVyXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB2bWwoJ2ZpbGwnLCB7Y29sb3I6IGdldENvbG9yKG8uY29sb3IsIGkpLCBvcGFjaXR5OiBvLm9wYWNpdHl9KSxcbiAgICAgICAgICAgICAgdm1sKCdzdHJva2UnLCB7b3BhY2l0eTogMH0pIC8vIHRyYW5zcGFyZW50IHN0cm9rZSB0byBmaXggY29sb3IgYmxlZWRpbmcgdXBvbiBvcGFjaXR5IGNoYW5nZVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBpZiAoby5zaGFkb3cpXG4gICAgICAgIGZvciAoaSA9IDE7IGkgPD0gby5saW5lczsgaSsrKVxuICAgICAgICAgIHNlZyhpLCAtMiwgJ3Byb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5CbHVyKHBpeGVscmFkaXVzPTIsbWFrZXNoYWRvdz0xLHNoYWRvd29wYWNpdHk9LjMpJylcblxuICAgICAgZm9yIChpID0gMTsgaSA8PSBvLmxpbmVzOyBpKyspIHNlZyhpKVxuICAgICAgcmV0dXJuIGlucyhlbCwgZylcbiAgICB9XG5cbiAgICBTcGlubmVyLnByb3RvdHlwZS5vcGFjaXR5ID0gZnVuY3Rpb24oZWwsIGksIHZhbCwgbykge1xuICAgICAgdmFyIGMgPSBlbC5maXJzdENoaWxkXG4gICAgICBvID0gby5zaGFkb3cgJiYgby5saW5lcyB8fCAwXG4gICAgICBpZiAoYyAmJiBpK28gPCBjLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgIGMgPSBjLmNoaWxkTm9kZXNbaStvXTsgYyA9IGMgJiYgYy5maXJzdENoaWxkOyBjID0gYyAmJiBjLmZpcnN0Q2hpbGRcbiAgICAgICAgaWYgKGMpIGMub3BhY2l0eSA9IHZhbFxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBwcm9iZSA9IGNzcyhjcmVhdGVFbCgnZ3JvdXAnKSwge2JlaGF2aW9yOiAndXJsKCNkZWZhdWx0I1ZNTCknfSlcblxuICBpZiAoIXZlbmRvcihwcm9iZSwgJ3RyYW5zZm9ybScpICYmIHByb2JlLmFkaikgaW5pdFZNTCgpXG4gIGVsc2UgdXNlQ3NzQW5pbWF0aW9ucyA9IHZlbmRvcihwcm9iZSwgJ2FuaW1hdGlvbicpXG5cbiAgcmV0dXJuIFNwaW5uZXJcblxufSkpO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICogQGVudW0ge051bWJlcn1cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIEVMRU1FTlQ6IDEsXG4gIEFUVFJJQlVURTogMixcbiAgVEVYVDogMyxcbiAgQ0RBVEFfU0VDVElPTjogNCxcbiAgRU5USVRZX1JFRkVSRU5DRTogNSxcbiAgRU5USVRZOiA2LFxuICBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OOiA3LFxuICBDT01NRU5UOiA4LFxuICBET0NVTUVOVDogOSxcbiAgRE9DVU1FTlRfVFlQRTogMTAsXG4gIERPQ1VNRU5UX0ZSQUdNRU5UOiAxMSxcbiAgTk9UQVRJT046IDEyXG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgbm90IHVuZGVmaW5lZC5cbiAqXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Qm9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBkZWZpbmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzRGVmKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSB2b2lkIDA7XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICogQWRkcyBhIGtleS12YWx1ZSBwYWlyIHRvIHRoZSBvYmplY3QvbWFwL2hhc2ggaWYgaXQgZG9lc24ndCBleGlzdCB5ZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3QuPEssVj59IG9iaiBUaGUgb2JqZWN0IHRvIHdoaWNoIHRvIGFkZCB0aGUga2V5LXZhbHVlIHBhaXIuXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5IFRoZSBrZXkgdG8gYWRkLlxuICogQHBhcmFtIHtWfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYWRkIGlmIHRoZSBrZXkgd2Fzbid0IHByZXNlbnQuXG4gKiBAcmV0dXJuIHtWfSBUaGUgdmFsdWUgb2YgdGhlIGVudHJ5IGF0IHRoZSBlbmQgb2YgdGhlIGZ1bmN0aW9uLlxuICogQHRlbXBsYXRlIEssVlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iaiwga2V5LCB2YWx1ZSkge1xuICByZXR1cm4ga2V5IGluIG9iaiA/IG9ialtrZXldIDogKG9ialtrZXldID0gdmFsdWUpO1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgaXNEZWYgPSByZXF1aXJlKCcuL2lzZGVmJyk7XG5cbi8qKlxuICogTWFrZSBzdXJlIHdlIHRyaW0gQk9NIGFuZCBOQlNQXG4gKiBAdHlwZSB7UmVnRXhwfVxuICovXG52YXIgVFJJTV9SRSA9IC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZztcblxuLyoqXG4gKiBSZXBlYXRzIGEgc3RyaW5nIG4gdGltZXMuXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcmVwZWF0LlxuICogQHBhcmFtIHtOdW1iZXJ9IGxlbmd0aCBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdC5cbiAqIEByZXR1cm4ge1N0cmluZ30gQSBzdHJpbmcgY29udGFpbmluZyB7QGNvZGUgbGVuZ3RofSByZXBldGl0aW9ucyBvZlxuICogICAgIHtAY29kZSBzdHJpbmd9LlxuICovXG5mdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBsZW5ndGgpIHtcbiAgcmV0dXJuIG5ldyBBcnJheShsZW5ndGggKyAxKS5qb2luKHN0cmluZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IHN0clxuICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAqL1xuICB0cmltOiBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoVFJJTV9SRSwgJycpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBQYWRzIG51bWJlciB0byBnaXZlbiBsZW5ndGggYW5kIG9wdGlvbmFsbHkgcm91bmRzIGl0IHRvIGEgZ2l2ZW4gcHJlY2lzaW9uLlxuICAgKiBGb3IgZXhhbXBsZTpcbiAgICogPHByZT5wYWROdW1iZXIoMS4yNSwgMiwgMykgLT4gJzAxLjI1MCdcbiAgICogcGFkTnVtYmVyKDEuMjUsIDIpIC0+ICcwMS4yNSdcbiAgICogcGFkTnVtYmVyKDEuMjUsIDIsIDEpIC0+ICcwMS4zJ1xuICAgKiBwYWROdW1iZXIoMS4yNSwgMCkgLT4gJzEuMjUnPC9wcmU+XG4gICAqXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBudW0gVGhlIG51bWJlciB0byBwYWQuXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIGRlc2lyZWQgbGVuZ3RoLlxuICAgKiBAcGFyYW0ge051bWJlcj19IG9wdF9wcmVjaXNpb24gVGhlIGRlc2lyZWQgcHJlY2lzaW9uLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHtAY29kZSBudW19IGFzIGEgc3RyaW5nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXG4gICAqL1xuICBwYWROdW1iZXI6IGZ1bmN0aW9uKG51bSwgbGVuZ3RoLCBvcHRfcHJlY2lzaW9uKSB7XG4gICAgdmFyIHMgPSBpc0RlZihvcHRfcHJlY2lzaW9uKSA/IG51bS50b0ZpeGVkKG9wdF9wcmVjaXNpb24pIDogU3RyaW5nKG51bSk7XG4gICAgdmFyIGluZGV4ID0gcy5pbmRleE9mKCcuJyk7XG4gICAgaWYgKGluZGV4ID09IC0xKSB7XG4gICAgICBpbmRleCA9IHMubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gcmVwZWF0KCcwJywgTWF0aC5tYXgoMCwgbGVuZ3RoIC0gaW5kZXgpKSArIHM7XG4gIH1cblxufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgWE1MUGFyc2VyID0gcmVxdWlyZSgnLi94bWxfcGFyc2VyJyk7XG52YXIgaXNEZWYgPSByZXF1aXJlKCcuL3V0aWxzL2lzZGVmJyk7XG52YXIgbm9kZVR5cGVzID0gcmVxdWlyZSgnLi9ub2RlX3R5cGVzJyk7XG52YXIgc2V0SWZVbmRlZmluZWQgPSByZXF1aXJlKCcuL3V0aWxzL3NldGlmdW5kZWZpbmVkJyk7XG52YXIgWFNEID0gcmVxdWlyZSgnLi94c2QnKTtcbnZhciBYTGluayA9IHJlcXVpcmUoJy4veGxpbmsnKTtcblxuLyoqXG4gKiBXTVMgQ2FwYWJpbGl0aWVzIHBhcnNlclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nPX0geG1sU3RyaW5nXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gV01TKHhtbFN0cmluZykge1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKi9cbiAgdGhpcy52ZXJzaW9uID0gdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7WE1MUGFyc2VyfVxuICAgKi9cbiAgdGhpcy5fcGFyc2VyID0gbmV3IFhNTFBhcnNlcigpO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7U3RyaW5nPX1cbiAgICovXG4gIHRoaXMuX2RhdGEgPSB4bWxTdHJpbmc7XG59O1xuXG4vKipcbiAqIFNob3J0Y3V0XG4gKiBAdHlwZSB7RnVuY3Rpb259XG4gKi9cbnZhciBtYWtlUHJvcGVydHlTZXR0ZXIgPSBYTUxQYXJzZXIubWFrZU9iamVjdFByb3BlcnR5U2V0dGVyO1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfSB4bWxTdHJpbmdcbiAqIEByZXR1cm4ge1dNU31cbiAqL1xuV01TLnByb3RvdHlwZS5kYXRhID0gZnVuY3Rpb24oeG1sU3RyaW5nKSB7XG4gIHRoaXMuX2RhdGEgPSB4bWxTdHJpbmc7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBAcGFyYW0gIHtTdHJpbmc9fSB4bWxTdHJpbmdcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuV01TLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbih4bWxTdHJpbmcpIHtcbiAgeG1sU3RyaW5nID0geG1sU3RyaW5nIHx8IHRoaXMuX2RhdGE7XG4gIHJldHVybiB0aGlzLnBhcnNlKHhtbFN0cmluZyk7XG59O1xuXG4vKipcbiAqIEByZXR1cm4ge1N0cmluZ30geG1sXG4gKi9cbldNUy5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbih4bWxTdHJpbmcpIHtcbiAgcmV0dXJuIHRoaXMuX3JlYWRGcm9tRG9jdW1lbnQodGhpcy5fcGFyc2VyLnRvRG9jdW1lbnQoeG1sU3RyaW5nKSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSAge0RvY3VtZW50fSBkb2NcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuV01TLnByb3RvdHlwZS5fcmVhZEZyb21Eb2N1bWVudCA9IGZ1bmN0aW9uKGRvYykge1xuICBmb3IgKHZhciBub2RlID0gZG9jLmZpcnN0Q2hpbGQ7IG5vZGU7IG5vZGUgPSBub2RlLm5leHRTaWJsaW5nKSB7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gbm9kZVR5cGVzLkVMRU1FTlQpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlYWRGcm9tTm9kZShub2RlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIEBwYXJhbSAge0RPTU5vZGV9IG5vZGVcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuV01TLnByb3RvdHlwZS5yZWFkRnJvbU5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gIHRoaXMudmVyc2lvbiA9IG5vZGUuZ2V0QXR0cmlidXRlKCd2ZXJzaW9uJyk7XG4gIHZhciB3bXNDYXBhYmlsaXR5T2JqZWN0ID0gWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcCh7XG4gICAgJ3ZlcnNpb24nOiB0aGlzLnZlcnNpb25cbiAgfSwgV01TLlBBUlNFUlMsIG5vZGUsIFtdKTtcblxuICByZXR1cm4gd21zQ2FwYWJpbGl0eU9iamVjdCB8fCBudWxsO1xufTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gQXR0cmlidXRpb24gb2JqZWN0LlxuICovXG5XTVMuX3JlYWRBdHRyaWJ1dGlvbiA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHJldHVybiBYTUxQYXJzZXIucHVzaFBhcnNlQW5kUG9wKHt9LCBXTVMuQVRUUklCVVRJT05fUEFSU0VSUywgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcmV0dXJuIHtPYmplY3R9IEJvdW5kaW5nIGJveCBvYmplY3QuXG4gKi9cbldNUy5fcmVhZEJvdW5kaW5nQm94ID0gZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgdmFyIHJlYWREZWNpbWFsU3RyaW5nID0gWFNELnJlYWREZWNpbWFsU3RyaW5nO1xuICB2YXIgZXh0ZW50ID0gW1xuICAgIHJlYWREZWNpbWFsU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdtaW54JykpLFxuICAgIHJlYWREZWNpbWFsU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdtaW55JykpLFxuICAgIHJlYWREZWNpbWFsU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdtYXh4JykpLFxuICAgIHJlYWREZWNpbWFsU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdtYXh5JykpXG4gIF07XG5cbiAgdmFyIHJlc29sdXRpb25zID0gW1xuICAgIHJlYWREZWNpbWFsU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdyZXN4JykpLFxuICAgIHJlYWREZWNpbWFsU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdyZXN5JykpXG4gIF07XG5cbiAgcmV0dXJuIHtcbiAgICAnY3JzJzogbm9kZS5nZXRBdHRyaWJ1dGUoJ0NSUycpIHx8IG5vZGUuZ2V0QXR0cmlidXRlKCdTUlMnKSxcbiAgICAnZXh0ZW50JzogZXh0ZW50LFxuICAgICdyZXMnOiByZXNvbHV0aW9uc1xuICB9O1xufTtcblxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcmV0dXJuIHtvbC5FeHRlbnR8dW5kZWZpbmVkfSBCb3VuZGluZyBib3ggb2JqZWN0LlxuICovXG5XTVMuX3JlYWRFWEdlb2dyYXBoaWNCb3VuZGluZ0JveCA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHZhciBnZW9ncmFwaGljQm91bmRpbmdCb3ggPSBYTUxQYXJzZXIucHVzaFBhcnNlQW5kUG9wKHt9LFxuICAgIFdNUy5FWF9HRU9HUkFQSElDX0JPVU5ESU5HX0JPWF9QQVJTRVJTLFxuICAgIG5vZGUsIG9iamVjdFN0YWNrKTtcbiAgaWYgKCFpc0RlZihnZW9ncmFwaGljQm91bmRpbmdCb3gpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHZhciB3ZXN0Qm91bmRMb25naXR1ZGUgPSAvKiogQHR5cGUge251bWJlcnx1bmRlZmluZWR9ICovXG4gICAgKGdlb2dyYXBoaWNCb3VuZGluZ0JveFsnd2VzdEJvdW5kTG9uZ2l0dWRlJ10pO1xuICB2YXIgc291dGhCb3VuZExhdGl0dWRlID0gLyoqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfSAqL1xuICAgIChnZW9ncmFwaGljQm91bmRpbmdCb3hbJ3NvdXRoQm91bmRMYXRpdHVkZSddKTtcbiAgdmFyIGVhc3RCb3VuZExvbmdpdHVkZSA9IC8qKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH0gKi9cbiAgICAoZ2VvZ3JhcGhpY0JvdW5kaW5nQm94WydlYXN0Qm91bmRMb25naXR1ZGUnXSk7XG4gIHZhciBub3J0aEJvdW5kTGF0aXR1ZGUgPSAvKiogQHR5cGUge251bWJlcnx1bmRlZmluZWR9ICovXG4gICAgKGdlb2dyYXBoaWNCb3VuZGluZ0JveFsnbm9ydGhCb3VuZExhdGl0dWRlJ10pO1xuXG4gIGlmICghaXNEZWYod2VzdEJvdW5kTG9uZ2l0dWRlKSB8fCAhaXNEZWYoc291dGhCb3VuZExhdGl0dWRlKSB8fFxuICAgICFpc0RlZihlYXN0Qm91bmRMb25naXR1ZGUpIHx8ICFpc0RlZihub3J0aEJvdW5kTGF0aXR1ZGUpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBbXG4gICAgd2VzdEJvdW5kTG9uZ2l0dWRlLCBzb3V0aEJvdW5kTGF0aXR1ZGUsXG4gICAgZWFzdEJvdW5kTG9uZ2l0dWRlLCBub3J0aEJvdW5kTGF0aXR1ZGVcbiAgXTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gQ2FwYWJpbGl0eSBvYmplY3QuXG4gKi9cbldNUy5fcmVhZENhcGFiaWxpdHkgPSBmdW5jdGlvbihub2RlLCBvYmplY3RTdGFjaykge1xuICByZXR1cm4gWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcCh7fSwgV01TLkNBUEFCSUxJVFlfUEFSU0VSUywgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHBhcmFtIHtBcnJheS48Kj59IG9iamVjdFN0YWNrIE9iamVjdCBzdGFjay5cbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBTZXJ2aWNlIG9iamVjdC5cbiAqL1xuV01TLl9yZWFkU2VydmljZSA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHJldHVybiBYTUxQYXJzZXIucHVzaFBhcnNlQW5kUG9wKHt9LCBXTVMuU0VSVklDRV9QQVJTRVJTLCBub2RlLCBvYmplY3RTdGFjayk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge09iamVjdHx1bmRlZmluZWR9IENvbnRhY3QgaW5mb3JtYXRpb24gb2JqZWN0LlxuICovXG5XTVMuX3JlYWRDb250YWN0SW5mb3JtYXRpb24gPSBmdW5jdGlvbihub2RlLCBvYmplY3RTdGFjaykge1xuICByZXR1cm4gWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcCh7fSwgV01TLkNPTlRBQ1RfSU5GT1JNQVRJT05fUEFSU0VSUyxcbiAgICBub2RlLCBvYmplY3RTdGFjayk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge09iamVjdHx1bmRlZmluZWR9IENvbnRhY3QgcGVyc29uIG9iamVjdC5cbiAqL1xuV01TLl9yZWFkQ29udGFjdFBlcnNvblByaW1hcnkgPSBmdW5jdGlvbihub2RlLCBvYmplY3RTdGFjaykge1xuICByZXR1cm4gWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcCh7fSwgV01TLkNPTlRBQ1RfUEVSU09OX1BBUlNFUlMsXG4gICAgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHBhcmFtIHtBcnJheS48Kj59IG9iamVjdFN0YWNrIE9iamVjdCBzdGFjay5cbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBDb250YWN0IGFkZHJlc3Mgb2JqZWN0LlxuICovXG5XTVMuX3JlYWRDb250YWN0QWRkcmVzcyA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHJldHVybiBYTUxQYXJzZXIucHVzaFBhcnNlQW5kUG9wKHt9LCBXTVMuQ09OVEFDVF9BRERSRVNTX1BBUlNFUlMsXG4gICAgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHBhcmFtIHtBcnJheS48Kj59IG9iamVjdFN0YWNrIE9iamVjdCBzdGFjay5cbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtBcnJheS48c3RyaW5nPnx1bmRlZmluZWR9IEZvcm1hdCBhcnJheS5cbiAqL1xuV01TLl9yZWFkRXhjZXB0aW9uID0gZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgcmV0dXJuIFhNTFBhcnNlci5wdXNoUGFyc2VBbmRQb3AoXG4gICAgW10sIFdNUy5FWENFUFRJT05fUEFSU0VSUywgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHBhcmFtIHtBcnJheS48Kj59IG9iamVjdFN0YWNrIE9iamVjdCBzdGFjay5cbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBMYXllciBvYmplY3QuXG4gKi9cbldNUy5fcmVhZENhcGFiaWxpdHlMYXllciA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHJldHVybiBYTUxQYXJzZXIucHVzaFBhcnNlQW5kUG9wKHt9LCBXTVMuTEFZRVJfUEFSU0VSUywgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBMYXllciBvYmplY3QuXG4gKi9cbldNUy5fcmVhZExheWVyID0gZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgdmFyIHBhcmVudExheWVyT2JqZWN0ID0gLyoqICBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsKj59ICovXG4gICAgKG9iamVjdFN0YWNrW29iamVjdFN0YWNrLmxlbmd0aCAtIDFdKTtcblxuICB2YXIgbGF5ZXJPYmplY3QgPSAvKiogIEB0eXBlIHtPYmplY3QuPHN0cmluZywqPn0gKi9cbiAgICAoWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcCh7fSwgV01TLkxBWUVSX1BBUlNFUlMsXG4gICAgICBub2RlLCBvYmplY3RTdGFjaykpO1xuXG4gIGlmICghaXNEZWYobGF5ZXJPYmplY3QpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHZhciBxdWVyeWFibGUgPSBYU0QucmVhZEJvb2xlYW5TdHJpbmcobm9kZS5nZXRBdHRyaWJ1dGUoJ3F1ZXJ5YWJsZScpKTtcbiAgaWYgKCFpc0RlZihxdWVyeWFibGUpKSB7XG4gICAgcXVlcnlhYmxlID0gcGFyZW50TGF5ZXJPYmplY3RbJ3F1ZXJ5YWJsZSddO1xuICB9XG4gIGxheWVyT2JqZWN0WydxdWVyeWFibGUnXSA9IGlzRGVmKHF1ZXJ5YWJsZSkgPyBxdWVyeWFibGUgOiBmYWxzZTtcblxuICB2YXIgY2FzY2FkZWQgPSBYU0QucmVhZE5vbk5lZ2F0aXZlSW50ZWdlclN0cmluZyhub2RlLmdldEF0dHJpYnV0ZSgnY2FzY2FkZWQnKSk7XG4gIGlmICghaXNEZWYoY2FzY2FkZWQpKSB7XG4gICAgY2FzY2FkZWQgPSBwYXJlbnRMYXllck9iamVjdFsnY2FzY2FkZWQnXTtcbiAgfVxuICBsYXllck9iamVjdFsnY2FzY2FkZWQnXSA9IGNhc2NhZGVkO1xuXG4gIHZhciBvcGFxdWUgPSBYU0QucmVhZEJvb2xlYW5TdHJpbmcobm9kZS5nZXRBdHRyaWJ1dGUoJ29wYXF1ZScpKTtcbiAgaWYgKCFpc0RlZihvcGFxdWUpKSB7XG4gICAgb3BhcXVlID0gcGFyZW50TGF5ZXJPYmplY3RbJ29wYXF1ZSddO1xuICB9XG4gIGxheWVyT2JqZWN0WydvcGFxdWUnXSA9IGlzRGVmKG9wYXF1ZSkgPyBvcGFxdWUgOiBmYWxzZTtcblxuICB2YXIgbm9TdWJzZXRzID0gWFNELnJlYWRCb29sZWFuU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdub1N1YnNldHMnKSk7XG4gIGlmICghaXNEZWYobm9TdWJzZXRzKSkge1xuICAgIG5vU3Vic2V0cyA9IHBhcmVudExheWVyT2JqZWN0Wydub1N1YnNldHMnXTtcbiAgfVxuICBsYXllck9iamVjdFsnbm9TdWJzZXRzJ10gPSBpc0RlZihub1N1YnNldHMpID8gbm9TdWJzZXRzIDogZmFsc2U7XG5cbiAgdmFyIGZpeGVkV2lkdGggPSBYU0QucmVhZERlY2ltYWxTdHJpbmcobm9kZS5nZXRBdHRyaWJ1dGUoJ2ZpeGVkV2lkdGgnKSk7XG4gIGlmICghaXNEZWYoZml4ZWRXaWR0aCkpIHtcbiAgICBmaXhlZFdpZHRoID0gcGFyZW50TGF5ZXJPYmplY3RbJ2ZpeGVkV2lkdGgnXTtcbiAgfVxuICBsYXllck9iamVjdFsnZml4ZWRXaWR0aCddID0gZml4ZWRXaWR0aDtcblxuICB2YXIgZml4ZWRIZWlnaHQgPSBYU0QucmVhZERlY2ltYWxTdHJpbmcobm9kZS5nZXRBdHRyaWJ1dGUoJ2ZpeGVkSGVpZ2h0JykpO1xuICBpZiAoIWlzRGVmKGZpeGVkSGVpZ2h0KSkge1xuICAgIGZpeGVkSGVpZ2h0ID0gcGFyZW50TGF5ZXJPYmplY3RbJ2ZpeGVkSGVpZ2h0J107XG4gIH1cbiAgbGF5ZXJPYmplY3RbJ2ZpeGVkSGVpZ2h0J10gPSBmaXhlZEhlaWdodDtcblxuICAvLyBTZWUgNy4yLjQuOFxuICB2YXIgYWRkS2V5cyA9IFsnU3R5bGUnLCAnQ1JTJywgJ0F1dGhvcml0eVVSTCddO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gYWRkS2V5cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIHZhciBrZXkgPSBhZGRLZXlzW2ldO1xuICAgIHZhciBwYXJlbnRWYWx1ZSA9IHBhcmVudExheWVyT2JqZWN0W2tleV07XG4gICAgaWYgKGlzRGVmKHBhcmVudFZhbHVlKSkge1xuICAgICAgdmFyIGNoaWxkVmFsdWUgPSBzZXRJZlVuZGVmaW5lZChsYXllck9iamVjdCwga2V5LCBbXSk7XG4gICAgICBjaGlsZFZhbHVlID0gY2hpbGRWYWx1ZS5jb25jYXQocGFyZW50VmFsdWUpO1xuICAgICAgbGF5ZXJPYmplY3Rba2V5XSA9IGNoaWxkVmFsdWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIHJlcGxhY2VLZXlzID0gWydFWF9HZW9ncmFwaGljQm91bmRpbmdCb3gnLCAnQm91bmRpbmdCb3gnLCAnRGltZW5zaW9uJyxcbiAgICAnQXR0cmlidXRpb24nLCAnTWluU2NhbGVEZW5vbWluYXRvcicsICdNYXhTY2FsZURlbm9taW5hdG9yJ1xuICBdO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmVwbGFjZUtleXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIga2V5ID0gcmVwbGFjZUtleXNbaV07XG4gICAgdmFyIGNoaWxkVmFsdWUgPSBsYXllck9iamVjdFtrZXldO1xuICAgIGlmICghaXNEZWYoY2hpbGRWYWx1ZSkpIHtcbiAgICAgIHZhciBwYXJlbnRWYWx1ZSA9IHBhcmVudExheWVyT2JqZWN0W2tleV07XG4gICAgICBsYXllck9iamVjdFtrZXldID0gcGFyZW50VmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxheWVyT2JqZWN0O1xufTtcblxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcmV0dXJuIHtPYmplY3R9IERpbWVuc2lvbiBvYmplY3QuXG4gKi9cbldNUy5fcmVhZERpbWVuc2lvbiA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHZhciBkaW1lbnNpb25PYmplY3QgPSB7XG4gICAgJ25hbWUnOiBub2RlLmdldEF0dHJpYnV0ZSgnbmFtZScpLFxuICAgICd1bml0cyc6IG5vZGUuZ2V0QXR0cmlidXRlKCd1bml0cycpLFxuICAgICd1bml0U3ltYm9sJzogbm9kZS5nZXRBdHRyaWJ1dGUoJ3VuaXRTeW1ib2wnKSxcbiAgICAnZGVmYXVsdCc6IG5vZGUuZ2V0QXR0cmlidXRlKCdkZWZhdWx0JyksXG4gICAgJ211bHRpcGxlVmFsdWVzJzogWFNELnJlYWRCb29sZWFuU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCdtdWx0aXBsZVZhbHVlcycpKSxcbiAgICAnbmVhcmVzdFZhbHVlJzogWFNELnJlYWRCb29sZWFuU3RyaW5nKG5vZGUuZ2V0QXR0cmlidXRlKCduZWFyZXN0VmFsdWUnKSksXG4gICAgJ2N1cnJlbnQnOiBYU0QucmVhZEJvb2xlYW5TdHJpbmcobm9kZS5nZXRBdHRyaWJ1dGUoJ2N1cnJlbnQnKSksXG4gICAgJ3ZhbHVlcyc6IFhTRC5yZWFkU3RyaW5nKG5vZGUpXG4gIH07XG4gIHJldHVybiBkaW1lbnNpb25PYmplY3Q7XG59O1xuXG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHBhcmFtIHtBcnJheS48Kj59IG9iamVjdFN0YWNrIE9iamVjdCBzdGFjay5cbiAqIEByZXR1cm4ge09iamVjdHx1bmRlZmluZWR9IE9ubGluZSByZXNvdXJjZSBvYmplY3QuXG4gKi9cbldNUy5fcmVhZEZvcm1hdE9ubGluZXJlc291cmNlID0gZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgcmV0dXJuIFhNTFBhcnNlci5wdXNoUGFyc2VBbmRQb3Aoe30sIFdNUy5GT1JNQVRfT05MSU5FUkVTT1VSQ0VfUEFSU0VSUyxcbiAgICBub2RlLCBvYmplY3RTdGFjayk7XG59O1xuXG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHBhcmFtIHtBcnJheS48Kj59IG9iamVjdFN0YWNrIE9iamVjdCBzdGFjay5cbiAqIEByZXR1cm4ge09iamVjdHx1bmRlZmluZWR9IFJlcXVlc3Qgb2JqZWN0LlxuICovXG5XTVMuX3JlYWRSZXF1ZXN0ID0gZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgcmV0dXJuIFhNTFBhcnNlci5wdXNoUGFyc2VBbmRQb3Aoe30sIFdNUy5SRVFVRVNUX1BBUlNFUlMsIG5vZGUsIG9iamVjdFN0YWNrKTtcbn07XG5cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gRENQIHR5cGUgb2JqZWN0LlxuICovXG5XTVMuX3JlYWREQ1BUeXBlID0gZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgcmV0dXJuIFhNTFBhcnNlci5wdXNoUGFyc2VBbmRQb3Aoe30sIFdNUy5EQ1BUWVBFX1BBUlNFUlMsIG5vZGUsIG9iamVjdFN0YWNrKTtcbn07XG5cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gSFRUUCBvYmplY3QuXG4gKi9cbldNUy5fcmVhZEhUVFAgPSBmdW5jdGlvbihub2RlLCBvYmplY3RTdGFjaykge1xuICByZXR1cm4gWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcCh7fSwgV01TLkhUVFBfUEFSU0VSUywgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBPcGVyYXRpb24gdHlwZSBvYmplY3QuXG4gKi9cbldNUy5fcmVhZE9wZXJhdGlvblR5cGUgPSBmdW5jdGlvbihub2RlLCBvYmplY3RTdGFjaykge1xuICByZXR1cm4gWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcCh7fSwgV01TLk9QRVJBVElPTlRZUEVfUEFSU0VSUywgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBPbmxpbmUgcmVzb3VyY2Ugb2JqZWN0LlxuICovXG5XTVMuX3JlYWRTaXplZEZvcm1hdE9ubGluZXJlc291cmNlID0gZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgdmFyIGZvcm1hdE9ubGluZXJlc291cmNlID0gV01TLl9yZWFkRm9ybWF0T25saW5lcmVzb3VyY2Uobm9kZSwgb2JqZWN0U3RhY2spO1xuICBpZiAoaXNEZWYoZm9ybWF0T25saW5lcmVzb3VyY2UpKSB7XG4gICAgdmFyIHJlYWROb25OZWdhdGl2ZUludGVnZXJTdHJpbmcgPSBYU0QucmVhZE5vbk5lZ2F0aXZlSW50ZWdlclN0cmluZztcbiAgICB2YXIgc2l6ZSA9IFtcbiAgICAgIHJlYWROb25OZWdhdGl2ZUludGVnZXJTdHJpbmcobm9kZS5nZXRBdHRyaWJ1dGUoJ3dpZHRoJykpLFxuICAgICAgcmVhZE5vbk5lZ2F0aXZlSW50ZWdlclN0cmluZyhub2RlLmdldEF0dHJpYnV0ZSgnaGVpZ2h0JykpXG4gICAgXTtcbiAgICBmb3JtYXRPbmxpbmVyZXNvdXJjZVsnc2l6ZSddID0gc2l6ZTtcbiAgICByZXR1cm4gZm9ybWF0T25saW5lcmVzb3VyY2U7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gQXV0aG9yaXR5IFVSTCBvYmplY3QuXG4gKi9cbldNUy5fcmVhZEF1dGhvcml0eVVSTCA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHZhciBhdXRob3JpdHlPYmplY3QgPSBXTVMuX3JlYWRGb3JtYXRPbmxpbmVyZXNvdXJjZShub2RlLCBvYmplY3RTdGFjayk7XG4gIGlmIChpc0RlZihhdXRob3JpdHlPYmplY3QpKSB7XG4gICAgYXV0aG9yaXR5T2JqZWN0WyduYW1lJ10gPSBub2RlLmdldEF0dHJpYnV0ZSgnbmFtZScpO1xuICAgIHJldHVybiBhdXRob3JpdHlPYmplY3Q7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gTWV0YWRhdGEgVVJMIG9iamVjdC5cbiAqL1xuV01TLl9yZWFkTWV0YWRhdGFVUkwgPSBmdW5jdGlvbihub2RlLCBvYmplY3RTdGFjaykge1xuICB2YXIgbWV0YWRhdGFPYmplY3QgPSBXTVMuX3JlYWRGb3JtYXRPbmxpbmVyZXNvdXJjZShub2RlLCBvYmplY3RTdGFjayk7XG4gIGlmIChpc0RlZihtZXRhZGF0YU9iamVjdCkpIHtcbiAgICBtZXRhZGF0YU9iamVjdFsndHlwZSddID0gbm9kZS5nZXRBdHRyaWJ1dGUoJ3R5cGUnKTtcbiAgICByZXR1cm4gbWV0YWRhdGFPYmplY3Q7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gU3R5bGUgb2JqZWN0LlxuICovXG5XTVMuX3JlYWRTdHlsZSA9IGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gIHJldHVybiBYTUxQYXJzZXIucHVzaFBhcnNlQW5kUG9wKHt9LCBXTVMuU1RZTEVfUEFSU0VSUywgbm9kZSwgb2JqZWN0U3RhY2spO1xufTtcblxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcmV0dXJuIHtBcnJheS48c3RyaW5nPnx1bmRlZmluZWR9IEtleXdvcmQgbGlzdC5cbiAqL1xuV01TLl9yZWFkS2V5d29yZExpc3QgPSBmdW5jdGlvbihub2RlLCBvYmplY3RTdGFjaykge1xuICByZXR1cm4gWE1MUGFyc2VyLnB1c2hQYXJzZUFuZFBvcChcbiAgICBbXSwgV01TLktFWVdPUkRMSVNUX1BBUlNFUlMsIG5vZGUsIG9iamVjdFN0YWNrKTtcbn07XG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7QXJyYXkuPHN0cmluZz59XG4gKi9cbldNUy5OQU1FU1BBQ0VfVVJJUyA9IFtcbiAgbnVsbCxcbiAgJ2h0dHA6Ly93d3cub3Blbmdpcy5uZXQvd21zJ1xuXTtcblxuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pn1cbiAqIEBwcml2YXRlXG4gKi9cbldNUy5QQVJTRVJTID0gWE1MUGFyc2VyLm1ha2VQYXJzZXJzTlMoXG4gIFdNUy5OQU1FU1BBQ0VfVVJJUywge1xuICAgICdTZXJ2aWNlJzogbWFrZVByb3BlcnR5U2V0dGVyKFdNUy5fcmVhZFNlcnZpY2UpLFxuICAgICdDYXBhYmlsaXR5JzogbWFrZVByb3BlcnR5U2V0dGVyKFdNUy5fcmVhZENhcGFiaWxpdHkpXG4gIH0pO1xuXG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge09iamVjdC48c3RyaW5nLCBPYmplY3QuPHN0cmluZywgWE1MUGFyc2VyLlBhcnNlcj4+fVxuICogQHByaXZhdGVcbiAqL1xuV01TLkNBUEFCSUxJVFlfUEFSU0VSUyA9IFhNTFBhcnNlci5tYWtlUGFyc2Vyc05TKFxuICBXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnUmVxdWVzdCc6IG1ha2VQcm9wZXJ0eVNldHRlcihXTVMuX3JlYWRSZXF1ZXN0KSxcbiAgICAnRXhjZXB0aW9uJzogbWFrZVByb3BlcnR5U2V0dGVyKFdNUy5fcmVhZEV4Y2VwdGlvbiksXG4gICAgJ0xheWVyJzogbWFrZVByb3BlcnR5U2V0dGVyKFdNUy5fcmVhZENhcGFiaWxpdHlMYXllcilcbiAgfSk7XG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuU0VSVklDRV9QQVJTRVJTID0gWE1MUGFyc2VyLm1ha2VQYXJzZXJzTlMoXG4gIFdNUy5OQU1FU1BBQ0VfVVJJUywge1xuICAgICdOYW1lJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnVGl0bGUnOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpLFxuICAgICdBYnN0cmFjdCc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ0tleXdvcmRMaXN0JzogbWFrZVByb3BlcnR5U2V0dGVyKFdNUy5fcmVhZEtleXdvcmRMaXN0KSxcbiAgICAnT25saW5lUmVzb3VyY2UnOiBtYWtlUHJvcGVydHlTZXR0ZXIoWExpbmsucmVhZEhyZWYpLFxuICAgICdDb250YWN0SW5mb3JtYXRpb24nOiBtYWtlUHJvcGVydHlTZXR0ZXIoV01TLl9yZWFkQ29udGFjdEluZm9ybWF0aW9uKSxcbiAgICAnRmVlcyc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ0FjY2Vzc0NvbnN0cmFpbnRzJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnTGF5ZXJMaW1pdCc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZE5vbk5lZ2F0aXZlSW50ZWdlciksXG4gICAgJ01heFdpZHRoJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkTm9uTmVnYXRpdmVJbnRlZ2VyKSxcbiAgICAnTWF4SGVpZ2h0JzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkTm9uTmVnYXRpdmVJbnRlZ2VyKVxuICB9KTtcblxuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pn1cbiAqIEBwcml2YXRlXG4gKi9cbldNUy5DT05UQUNUX0lORk9STUFUSU9OX1BBUlNFUlMgPSBYTUxQYXJzZXIubWFrZVBhcnNlcnNOUyhcbiAgV01TLk5BTUVTUEFDRV9VUklTLCB7XG4gICAgJ0NvbnRhY3RQZXJzb25QcmltYXJ5JzogbWFrZVByb3BlcnR5U2V0dGVyKFdNUy5fcmVhZENvbnRhY3RQZXJzb25QcmltYXJ5KSxcbiAgICAnQ29udGFjdFBvc2l0aW9uJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnQ29udGFjdEFkZHJlc3MnOiBtYWtlUHJvcGVydHlTZXR0ZXIoV01TLl9yZWFkQ29udGFjdEFkZHJlc3MpLFxuICAgICdDb250YWN0Vm9pY2VUZWxlcGhvbmUnOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpLFxuICAgICdDb250YWN0RmFjc2ltaWxlVGVsZXBob25lJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnQ29udGFjdEVsZWN0cm9uaWNNYWlsQWRkcmVzcyc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZylcbiAgfSk7XG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuQ09OVEFDVF9QRVJTT05fUEFSU0VSUyA9IFhNTFBhcnNlci5tYWtlUGFyc2Vyc05TKFxuICBXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnQ29udGFjdFBlcnNvbic6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ0NvbnRhY3RPcmdhbml6YXRpb24nOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpXG4gIH0pO1xuXG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuQ09OVEFDVF9BRERSRVNTX1BBUlNFUlMgPSBYTUxQYXJzZXIubWFrZVBhcnNlcnNOUyhcbiAgV01TLk5BTUVTUEFDRV9VUklTLCB7XG4gICAgJ0FkZHJlc3NUeXBlJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnQWRkcmVzcyc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ0NpdHknOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpLFxuICAgICdTdGF0ZU9yUHJvdmluY2UnOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpLFxuICAgICdQb3N0Q29kZSc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ0NvdW50cnknOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpXG4gIH0pO1xuXG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuRVhDRVBUSU9OX1BBUlNFUlMgPSBYTUxQYXJzZXIubWFrZVBhcnNlcnNOUyhcbiAgV01TLk5BTUVTUEFDRV9VUklTLCB7XG4gICAgJ0Zvcm1hdCc6IFhNTFBhcnNlci5tYWtlQXJyYXlQdXNoZXIoWFNELnJlYWRTdHJpbmcpXG4gIH0pO1xuXG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuTEFZRVJfUEFSU0VSUyA9IFhNTFBhcnNlci5tYWtlUGFyc2Vyc05TKFxuICBXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnTmFtZSc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ1RpdGxlJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnQWJzdHJhY3QnOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpLFxuICAgICdLZXl3b3JkTGlzdCc6IG1ha2VQcm9wZXJ0eVNldHRlcihXTVMuX3JlYWRLZXl3b3JkTGlzdCksXG4gICAgJ0NSUyc6IFhNTFBhcnNlci5tYWtlT2JqZWN0UHJvcGVydHlQdXNoZXIoWFNELnJlYWRTdHJpbmcpLFxuICAgICdFWF9HZW9ncmFwaGljQm91bmRpbmdCb3gnOiBtYWtlUHJvcGVydHlTZXR0ZXIoV01TLl9yZWFkRVhHZW9ncmFwaGljQm91bmRpbmdCb3gpLFxuICAgICdCb3VuZGluZ0JveCc6IFhNTFBhcnNlci5tYWtlT2JqZWN0UHJvcGVydHlQdXNoZXIoV01TLl9yZWFkQm91bmRpbmdCb3gpLFxuICAgICdEaW1lbnNpb24nOiBYTUxQYXJzZXIubWFrZU9iamVjdFByb3BlcnR5UHVzaGVyKFdNUy5fcmVhZERpbWVuc2lvbiksXG4gICAgJ0F0dHJpYnV0aW9uJzogbWFrZVByb3BlcnR5U2V0dGVyKFdNUy5fcmVhZEF0dHJpYnV0aW9uKSxcbiAgICAnQXV0aG9yaXR5VVJMJzogWE1MUGFyc2VyLm1ha2VPYmplY3RQcm9wZXJ0eVB1c2hlcihXTVMuX3JlYWRBdXRob3JpdHlVUkwpLFxuICAgICdJZGVudGlmaWVyJzogWE1MUGFyc2VyLm1ha2VPYmplY3RQcm9wZXJ0eVB1c2hlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ01ldGFkYXRhVVJMJzogWE1MUGFyc2VyLm1ha2VPYmplY3RQcm9wZXJ0eVB1c2hlcihXTVMuX3JlYWRNZXRhZGF0YVVSTCksXG4gICAgJ0RhdGFVUkwnOiBYTUxQYXJzZXIubWFrZU9iamVjdFByb3BlcnR5UHVzaGVyKFdNUy5fcmVhZEZvcm1hdE9ubGluZXJlc291cmNlKSxcbiAgICAnRmVhdHVyZUxpc3RVUkwnOiBYTUxQYXJzZXIubWFrZU9iamVjdFByb3BlcnR5UHVzaGVyKFdNUy5fcmVhZEZvcm1hdE9ubGluZXJlc291cmNlKSxcbiAgICAnU3R5bGUnOiBYTUxQYXJzZXIubWFrZU9iamVjdFByb3BlcnR5UHVzaGVyKFdNUy5fcmVhZFN0eWxlKSxcbiAgICAnTWluU2NhbGVEZW5vbWluYXRvcic6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZERlY2ltYWwpLFxuICAgICdNYXhTY2FsZURlbm9taW5hdG9yJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkRGVjaW1hbCksXG4gICAgJ0xheWVyJzogWE1MUGFyc2VyLm1ha2VPYmplY3RQcm9wZXJ0eVB1c2hlcihXTVMuX3JlYWRMYXllcilcbiAgfSk7XG5cblxuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pn1cbiAqIEBwcml2YXRlXG4gKi9cbldNUy5BVFRSSUJVVElPTl9QQVJTRVJTID0gWE1MUGFyc2VyLm1ha2VQYXJzZXJzTlMoXG4gIFdNUy5OQU1FU1BBQ0VfVVJJUywge1xuICAgICdUaXRsZSc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ09ubGluZVJlc291cmNlJzogbWFrZVByb3BlcnR5U2V0dGVyKFhMaW5rLnJlYWRIcmVmKSxcbiAgICAnTG9nb1VSTCc6IG1ha2VQcm9wZXJ0eVNldHRlcihXTVMuX3JlYWRTaXplZEZvcm1hdE9ubGluZXJlc291cmNlKVxuICB9KTtcblxuXG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge09iamVjdC48c3RyaW5nLCBPYmplY3QuPHN0cmluZywgWE1MUGFyc2VyLlBhcnNlcj4+fVxuICogQHByaXZhdGVcbiAqL1xuV01TLkVYX0dFT0dSQVBISUNfQk9VTkRJTkdfQk9YX1BBUlNFUlMgPVxuICBYTUxQYXJzZXIubWFrZVBhcnNlcnNOUyhXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnd2VzdEJvdW5kTG9uZ2l0dWRlJzogbWFrZVByb3BlcnR5U2V0dGVyKFxuICAgICAgWFNELnJlYWREZWNpbWFsKSxcbiAgICAnZWFzdEJvdW5kTG9uZ2l0dWRlJzogbWFrZVByb3BlcnR5U2V0dGVyKFxuICAgICAgWFNELnJlYWREZWNpbWFsKSxcbiAgICAnc291dGhCb3VuZExhdGl0dWRlJzogbWFrZVByb3BlcnR5U2V0dGVyKFxuICAgICAgWFNELnJlYWREZWNpbWFsKSxcbiAgICAnbm9ydGhCb3VuZExhdGl0dWRlJzogbWFrZVByb3BlcnR5U2V0dGVyKFxuICAgICAgWFNELnJlYWREZWNpbWFsKVxuICB9KTtcblxuXG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge09iamVjdC48c3RyaW5nLCBPYmplY3QuPHN0cmluZywgWE1MUGFyc2VyLlBhcnNlcj4+fVxuICogQHByaXZhdGVcbiAqL1xuV01TLlJFUVVFU1RfUEFSU0VSUyA9IFhNTFBhcnNlci5tYWtlUGFyc2Vyc05TKFxuICBXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnR2V0Q2FwYWJpbGl0aWVzJzogbWFrZVByb3BlcnR5U2V0dGVyKFxuICAgICAgV01TLl9yZWFkT3BlcmF0aW9uVHlwZSksXG4gICAgJ0dldE1hcCc6IG1ha2VQcm9wZXJ0eVNldHRlcihcbiAgICAgIFdNUy5fcmVhZE9wZXJhdGlvblR5cGUpLFxuICAgICdHZXRGZWF0dXJlSW5mbyc6IG1ha2VQcm9wZXJ0eVNldHRlcihcbiAgICAgIFdNUy5fcmVhZE9wZXJhdGlvblR5cGUpXG4gIH0pO1xuXG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuT1BFUkFUSU9OVFlQRV9QQVJTRVJTID0gWE1MUGFyc2VyLm1ha2VQYXJzZXJzTlMoXG4gIFdNUy5OQU1FU1BBQ0VfVVJJUywge1xuICAgICdGb3JtYXQnOiBYTUxQYXJzZXIubWFrZU9iamVjdFByb3BlcnR5UHVzaGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnRENQVHlwZSc6IFhNTFBhcnNlci5tYWtlT2JqZWN0UHJvcGVydHlQdXNoZXIoXG4gICAgICBXTVMuX3JlYWREQ1BUeXBlKVxuICB9KTtcblxuXG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge09iamVjdC48c3RyaW5nLCBPYmplY3QuPHN0cmluZywgWE1MUGFyc2VyLlBhcnNlcj4+fVxuICogQHByaXZhdGVcbiAqL1xuV01TLkRDUFRZUEVfUEFSU0VSUyA9IFhNTFBhcnNlci5tYWtlUGFyc2Vyc05TKFxuICBXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnSFRUUCc6IG1ha2VQcm9wZXJ0eVNldHRlcihcbiAgICAgIFdNUy5fcmVhZEhUVFApXG4gIH0pO1xuXG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuSFRUUF9QQVJTRVJTID0gWE1MUGFyc2VyLm1ha2VQYXJzZXJzTlMoXG4gIFdNUy5OQU1FU1BBQ0VfVVJJUywge1xuICAgICdHZXQnOiBtYWtlUHJvcGVydHlTZXR0ZXIoXG4gICAgICBXTVMuX3JlYWRGb3JtYXRPbmxpbmVyZXNvdXJjZSksXG4gICAgJ1Bvc3QnOiBtYWtlUHJvcGVydHlTZXR0ZXIoXG4gICAgICBXTVMuX3JlYWRGb3JtYXRPbmxpbmVyZXNvdXJjZSlcbiAgfSk7XG5cblxuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pn1cbiAqIEBwcml2YXRlXG4gKi9cbldNUy5TVFlMRV9QQVJTRVJTID0gWE1MUGFyc2VyLm1ha2VQYXJzZXJzTlMoXG4gIFdNUy5OQU1FU1BBQ0VfVVJJUywge1xuICAgICdOYW1lJzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnVGl0bGUnOiBtYWtlUHJvcGVydHlTZXR0ZXIoWFNELnJlYWRTdHJpbmcpLFxuICAgICdBYnN0cmFjdCc6IG1ha2VQcm9wZXJ0eVNldHRlcihYU0QucmVhZFN0cmluZyksXG4gICAgJ0xlZ2VuZFVSTCc6IFhNTFBhcnNlci5tYWtlT2JqZWN0UHJvcGVydHlQdXNoZXIoV01TLl9yZWFkU2l6ZWRGb3JtYXRPbmxpbmVyZXNvdXJjZSksXG4gICAgJ1N0eWxlU2hlZXRVUkwnOiBtYWtlUHJvcGVydHlTZXR0ZXIoV01TLl9yZWFkRm9ybWF0T25saW5lcmVzb3VyY2UpLFxuICAgICdTdHlsZVVSTCc6IG1ha2VQcm9wZXJ0eVNldHRlcihXTVMuX3JlYWRGb3JtYXRPbmxpbmVyZXNvdXJjZSlcbiAgfSk7XG5cblxuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pn1cbiAqIEBwcml2YXRlXG4gKi9cbldNUy5GT1JNQVRfT05MSU5FUkVTT1VSQ0VfUEFSU0VSUyA9IFhNTFBhcnNlci5tYWtlUGFyc2Vyc05TKFxuICBXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnRm9ybWF0JzogbWFrZVByb3BlcnR5U2V0dGVyKFhTRC5yZWFkU3RyaW5nKSxcbiAgICAnT25saW5lUmVzb3VyY2UnOiBtYWtlUHJvcGVydHlTZXR0ZXIoWExpbmsucmVhZEhyZWYpXG4gIH0pO1xuXG5cbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsIE9iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPj59XG4gKiBAcHJpdmF0ZVxuICovXG5XTVMuS0VZV09SRExJU1RfUEFSU0VSUyA9IFhNTFBhcnNlci5tYWtlUGFyc2Vyc05TKFxuICBXTVMuTkFNRVNQQUNFX1VSSVMsIHtcbiAgICAnS2V5d29yZCc6IFhNTFBhcnNlci5tYWtlQXJyYXlQdXNoZXIoWFNELnJlYWRTdHJpbmcpXG4gIH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdNUztcbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xudmFyIE5BTUVTUEFDRV9VUkkgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAgICogQHJldHVybiB7Qm9vbGVhbnx1bmRlZmluZWR9IEJvb2xlYW4uXG4gICAqL1xuICByZWFkSHJlZjogZnVuY3Rpb24obm9kZSkge1xuICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZU5TKE5BTUVTUEFDRV9VUkksICdocmVmJyk7XG4gIH1cbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGlzRGVmID0gcmVxdWlyZSgnLi91dGlscy9pc2RlZicpO1xudmFyIHNldElmVW5kZWZpbmVkID0gcmVxdWlyZSgnLi91dGlscy9zZXRpZnVuZGVmaW5lZCcpO1xudmFyIG5vZGVUeXBlcyA9IHJlcXVpcmUoJy4vbm9kZV90eXBlcycpO1xuXG4vKipcbiAqIFhNTCBET00gcGFyc2VyXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gWE1MUGFyc2VyKCkge1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7RE9NUGFyc2VyfVxuICAgKi9cbiAgdGhpcy5fcGFyc2VyID0gbmV3IERPTVBhcnNlcigpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHhtbHN0cmluZ1xuICogQHJldHVybiB7RG9jdW1lbnR9XG4gKi9cblhNTFBhcnNlci5wcm90b3R5cGUudG9Eb2N1bWVudCA9IGZ1bmN0aW9uKHhtbHN0cmluZykge1xuICByZXR1cm4gdGhpcy5fcGFyc2VyLnBhcnNlRnJvbVN0cmluZyh4bWxzdHJpbmcsICdhcHBsaWNhdGlvbi94bWwnKTtcbn07XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgZ3JhYiBhbGwgdGV4dCBjb250ZW50IG9mIGNoaWxkIG5vZGVzIGludG8gYSBzaW5nbGUgc3RyaW5nLlxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZVdoaXRlc3BhY2UgTm9ybWFsaXplIHdoaXRlc3BhY2U6IHJlbW92ZSBhbGwgbGluZVxuICogYnJlYWtzLlxuICogQHJldHVybiB7c3RyaW5nfSBBbGwgdGV4dCBjb250ZW50LlxuICogQGFwaVxuICovXG5YTUxQYXJzZXIuZ2V0QWxsVGV4dENvbnRlbnQgPSBmdW5jdGlvbihub2RlLCBub3JtYWxpemVXaGl0ZXNwYWNlKSB7XG4gIHJldHVybiBYTUxQYXJzZXIuZ2V0QWxsVGV4dENvbnRlbnRfKG5vZGUsIG5vcm1hbGl6ZVdoaXRlc3BhY2UsIFtdKS5qb2luKCcnKTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9ybWFsaXplV2hpdGVzcGFjZSBOb3JtYWxpemUgd2hpdGVzcGFjZTogcmVtb3ZlIGFsbCBsaW5lXG4gKiBicmVha3MuXG4gKiBAcGFyYW0ge0FycmF5LjxTdHJpbmd8c3RyaW5nPn0gYWNjdW11bGF0b3IgQWNjdW11bGF0b3IuXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7QXJyYXkuPFN0cmluZ3xzdHJpbmc+fSBBY2N1bXVsYXRvci5cbiAqL1xuWE1MUGFyc2VyLmdldEFsbFRleHRDb250ZW50XyA9IGZ1bmN0aW9uKG5vZGUsIG5vcm1hbGl6ZVdoaXRlc3BhY2UsIGFjY3VtdWxhdG9yKSB7XG4gIGlmIChub2RlLm5vZGVUeXBlID09PSBub2RlVHlwZXMuQ0RBVEFfU0VDVElPTiB8fFxuICAgIG5vZGUubm9kZVR5cGUgPT09IG5vZGVUeXBlcy5URVhUKSB7XG4gICAgaWYgKG5vcm1hbGl6ZVdoaXRlc3BhY2UpIHtcbiAgICAgIC8vIEZJWE1FIHVuZGVyc3RhbmQgd2h5IGdvb2cuZG9tLmdldFRleHRDb250ZW50XyB1c2VzIFN0cmluZyBoZXJlXG4gICAgICBhY2N1bXVsYXRvci5wdXNoKFN0cmluZyhub2RlLm5vZGVWYWx1ZSkucmVwbGFjZSgvKFxcclxcbnxcXHJ8XFxuKS9nLCAnJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2N1bXVsYXRvci5wdXNoKG5vZGUubm9kZVZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIG47XG4gICAgZm9yIChuID0gbm9kZS5maXJzdENoaWxkOyBuOyBuID0gbi5uZXh0U2libGluZykge1xuICAgICAgWE1MUGFyc2VyLmdldEFsbFRleHRDb250ZW50XyhuLCBub3JtYWxpemVXaGl0ZXNwYWNlLCBhY2N1bXVsYXRvcik7XG4gICAgfVxuICB9XG4gIHJldHVybiBhY2N1bXVsYXRvcjtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pn0gcGFyc2Vyc05TXG4gKiAgICAgUGFyc2VycyBieSBuYW1lc3BhY2UuXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gKiBAcGFyYW0geyo9fSBiaW5kIFRoZSBvYmplY3QgdG8gdXNlIGFzIGB0aGlzYC5cbiAqL1xuWE1MUGFyc2VyLnBhcnNlTm9kZSA9IGZ1bmN0aW9uKHBhcnNlcnNOUywgbm9kZSwgb2JqZWN0U3RhY2ssIGJpbmQpIHtcbiAgZm9yICh2YXIgbiA9IFhNTFBhcnNlci5maXJzdEVsZW1lbnRDaGlsZChub2RlKTsgbjsgbiA9IFhNTFBhcnNlci5uZXh0RWxlbWVudFNpYmxpbmcobikpIHtcbiAgICB2YXIgbmFtZXNwYWNlVVJJID0gbi5uYW1lc3BhY2VVUkkgfHwgbnVsbDtcbiAgICB2YXIgcGFyc2VycyA9IHBhcnNlcnNOU1tuYW1lc3BhY2VVUkldO1xuICAgIGlmIChpc0RlZihwYXJzZXJzKSkge1xuICAgICAgdmFyIHBhcnNlciA9IHBhcnNlcnNbbi5sb2NhbE5hbWVdO1xuICAgICAgaWYgKGlzRGVmKHBhcnNlcikpIHtcbiAgICAgICAgcGFyc2VyLmNhbGwoYmluZCwgbiwgb2JqZWN0U3RhY2spO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBNb3N0bHkgZm9yIG5vZGUuanNcbiAqIEBwYXJhbSAge05vZGV9IG5vZGVcbiAqIEByZXR1cm4ge05vZGV9XG4gKi9cblhNTFBhcnNlci5maXJzdEVsZW1lbnRDaGlsZCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIGZpcnN0RWxlbWVudENoaWxkID0gbm9kZS5maXJzdEVsZW1lbnRDaGlsZCB8fCBub2RlLmZpcnN0Q2hpbGQ7XG4gIHdoaWxlIChmaXJzdEVsZW1lbnRDaGlsZCAmJiBmaXJzdEVsZW1lbnRDaGlsZC5ub2RlVHlwZSAhPT0gbm9kZVR5cGVzLkVMRU1FTlQpIHtcbiAgICBmaXJzdEVsZW1lbnRDaGlsZCA9IGZpcnN0RWxlbWVudENoaWxkLm5leHRTaWJsaW5nO1xuICB9XG4gIHJldHVybiBmaXJzdEVsZW1lbnRDaGlsZDtcbn07XG5cbi8qKlxuICogTW9zdGx5IGZvciBub2RlLmpzXG4gKiBAcGFyYW0gIHtOb2RlfSBub2RlXG4gKiBAcmV0dXJuIHtOb2RlfVxuICovXG5YTUxQYXJzZXIubmV4dEVsZW1lbnRTaWJsaW5nID0gZnVuY3Rpb24obm9kZSkge1xuICB2YXIgbmV4dEVsZW1lbnRTaWJsaW5nID0gbm9kZS5uZXh0RWxlbWVudFNpYmxpbmcgfHwgbm9kZS5uZXh0U2libGluZztcbiAgd2hpbGUgKG5leHRFbGVtZW50U2libGluZyAmJiBuZXh0RWxlbWVudFNpYmxpbmcubm9kZVR5cGUgIT09IG5vZGVUeXBlcy5FTEVNRU5UKSB7XG4gICAgbmV4dEVsZW1lbnRTaWJsaW5nID0gbmV4dEVsZW1lbnRTaWJsaW5nLm5leHRTaWJsaW5nO1xuICB9XG4gIHJldHVybiBuZXh0RWxlbWVudFNpYmxpbmc7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXkuPHN0cmluZz59IG5hbWVzcGFjZVVSSXMgTmFtZXNwYWNlIFVSSXMuXG4gKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCBYTUxQYXJzZXIuUGFyc2VyPn0gcGFyc2VycyBQYXJzZXJzLlxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pj19IG9wdF9wYXJzZXJzTlNcbiAqICAgICBQYXJzZXJzTlMuXG4gKiBAcmV0dXJuIHtPYmplY3QuPHN0cmluZywgT2JqZWN0LjxzdHJpbmcsIFhNTFBhcnNlci5QYXJzZXI+Pn0gUGFyc2VycyBOUy5cbiAqL1xuWE1MUGFyc2VyLm1ha2VQYXJzZXJzTlMgPSBmdW5jdGlvbihuYW1lc3BhY2VVUklzLCBwYXJzZXJzLCBvcHRfcGFyc2Vyc05TKSB7XG4gIHJldHVybiAvKiogQHR5cGUge09iamVjdC48c3RyaW5nLCBPYmplY3QuPHN0cmluZywgWE1MUGFyc2VyLlBhcnNlcj4+fSAqLyAoXG4gICAgWE1MUGFyc2VyLm1ha2VTdHJ1Y3R1cmVOUyhuYW1lc3BhY2VVUklzLCBwYXJzZXJzLCBvcHRfcGFyc2Vyc05TKSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuYW1lc3BhY2VkIHN0cnVjdHVyZSwgdXNpbmcgdGhlIHNhbWUgdmFsdWVzIGZvciBlYWNoIG5hbWVzcGFjZS5cbiAqIFRoaXMgY2FuIGJlIHVzZWQgYXMgYSBzdGFydGluZyBwb2ludCBmb3IgdmVyc2lvbmVkIHBhcnNlcnMsIHdoZW4gb25seSBhIGZld1xuICogdmFsdWVzIGFyZSB2ZXJzaW9uIHNwZWNpZmljLlxuICogQHBhcmFtIHtBcnJheS48c3RyaW5nPn0gbmFtZXNwYWNlVVJJcyBOYW1lc3BhY2UgVVJJcy5cbiAqIEBwYXJhbSB7VH0gc3RydWN0dXJlIFN0cnVjdHVyZS5cbiAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsIFQ+PX0gb3B0X3N0cnVjdHVyZU5TIE5hbWVzcGFjZWQgc3RydWN0dXJlIHRvIGFkZCB0by5cbiAqIEByZXR1cm4ge09iamVjdC48c3RyaW5nLCBUPn0gTmFtZXNwYWNlZCBzdHJ1Y3R1cmUuXG4gKiBAdGVtcGxhdGUgVFxuICovXG5YTUxQYXJzZXIubWFrZVN0cnVjdHVyZU5TID0gZnVuY3Rpb24obmFtZXNwYWNlVVJJcywgc3RydWN0dXJlLCBvcHRfc3RydWN0dXJlTlMpIHtcbiAgLyoqXG4gICAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywgKj59XG4gICAqL1xuICB2YXIgc3RydWN0dXJlTlMgPSBpc0RlZihvcHRfc3RydWN0dXJlTlMpID8gb3B0X3N0cnVjdHVyZU5TIDoge307XG4gIHZhciBpLCBpaTtcbiAgZm9yIChpID0gMCwgaWkgPSBuYW1lc3BhY2VVUklzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBzdHJ1Y3R1cmVOU1tuYW1lc3BhY2VVUklzW2ldXSA9IHN0cnVjdHVyZTtcbiAgfVxuICByZXR1cm4gc3RydWN0dXJlTlM7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczogVCwgTm9kZSwgQXJyYXkuPCo+KTogKn0gdmFsdWVSZWFkZXIgVmFsdWUgcmVhZGVyLlxuICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfcHJvcGVydHkgUHJvcGVydHkuXG4gKiBAcGFyYW0ge1Q9fSBvcHRfdGhpcyBUaGUgb2JqZWN0IHRvIHVzZSBhcyBgdGhpc2AgaW4gYHZhbHVlUmVhZGVyYC5cbiAqIEByZXR1cm4ge1hNTFBhcnNlci5QYXJzZXJ9IFBhcnNlci5cbiAqIEB0ZW1wbGF0ZSBUXG4gKi9cblhNTFBhcnNlci5tYWtlT2JqZWN0UHJvcGVydHlTZXR0ZXIgPSBmdW5jdGlvbih2YWx1ZVJlYWRlciwgb3B0X3Byb3BlcnR5LCBvcHRfdGhpcykge1xuICByZXR1cm4gKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICAgICAqIEBwYXJhbSB7QXJyYXkuPCo+fSBvYmplY3RTdGFjayBPYmplY3Qgc3RhY2suXG4gICAgICovXG4gICAgZnVuY3Rpb24obm9kZSwgb2JqZWN0U3RhY2spIHtcbiAgICAgIHZhciB2YWx1ZSA9IHZhbHVlUmVhZGVyLmNhbGwoaXNEZWYob3B0X3RoaXMpID8gb3B0X3RoaXMgOiB0aGlzLFxuICAgICAgICBub2RlLCBvYmplY3RTdGFjayk7XG4gICAgICBpZiAoaXNEZWYodmFsdWUpKSB7XG4gICAgICAgIHZhciBvYmplY3QgPSAvKiogQHR5cGUge09iamVjdH0gKi8gKG9iamVjdFN0YWNrW29iamVjdFN0YWNrLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgdmFyIHByb3BlcnR5ID0gaXNEZWYob3B0X3Byb3BlcnR5KSA/IG9wdF9wcm9wZXJ0eSA6IG5vZGUubG9jYWxOYW1lO1xuICAgICAgICBvYmplY3RbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczogVCwgTm9kZSwgQXJyYXkuPCo+KTogKn0gdmFsdWVSZWFkZXIgVmFsdWUgcmVhZGVyLlxuICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfcHJvcGVydHkgUHJvcGVydHkuXG4gKiBAcGFyYW0ge1Q9fSBvcHRfdGhpcyBUaGUgb2JqZWN0IHRvIHVzZSBhcyBgdGhpc2AgaW4gYHZhbHVlUmVhZGVyYC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBQYXJzZXIuXG4gKiBAdGVtcGxhdGUgVFxuICovXG5YTUxQYXJzZXIubWFrZU9iamVjdFByb3BlcnR5UHVzaGVyID0gZnVuY3Rpb24odmFsdWVSZWFkZXIsIG9wdF9wcm9wZXJ0eSwgb3B0X3RoaXMpIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gICAgICB2YXIgdmFsdWUgPSB2YWx1ZVJlYWRlci5jYWxsKGlzRGVmKG9wdF90aGlzKSA/IG9wdF90aGlzIDogdGhpcyxcbiAgICAgICAgbm9kZSwgb2JqZWN0U3RhY2spO1xuXG4gICAgICBpZiAoaXNEZWYodmFsdWUpKSB7XG4gICAgICAgIHZhciBvYmplY3QgPSAvKiogQHR5cGUge09iamVjdH0gKi8gKG9iamVjdFN0YWNrW29iamVjdFN0YWNrLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgdmFyIHByb3BlcnR5ID0gaXNEZWYob3B0X3Byb3BlcnR5KSA/IG9wdF9wcm9wZXJ0eSA6IG5vZGUubG9jYWxOYW1lO1xuICAgICAgICB2YXIgYXJyYXkgPSBzZXRJZlVuZGVmaW5lZChvYmplY3QsIHByb3BlcnR5LCBbXSk7XG4gICAgICAgIGFycmF5LnB1c2godmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6IFQsIE5vZGUsIEFycmF5LjwqPik6ICp9IHZhbHVlUmVhZGVyIFZhbHVlIHJlYWRlci5cbiAqIEBwYXJhbSB7VD19IG9wdF90aGlzIFRoZSBvYmplY3QgdG8gdXNlIGFzIGB0aGlzYCBpbiBgdmFsdWVSZWFkZXJgLlxuICogQHJldHVybiB7RnVuY3Rpb259IFBhcnNlci5cbiAqIEB0ZW1wbGF0ZSBUXG4gKi9cblhNTFBhcnNlci5tYWtlQXJyYXlQdXNoZXIgPSBmdW5jdGlvbih2YWx1ZVJlYWRlciwgb3B0X3RoaXMpIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5LjwqPn0gb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uKG5vZGUsIG9iamVjdFN0YWNrKSB7XG4gICAgICB2YXIgdmFsdWUgPSB2YWx1ZVJlYWRlci5jYWxsKGlzRGVmKG9wdF90aGlzKSA/IG9wdF90aGlzIDogdGhpcyxcbiAgICAgICAgbm9kZSwgb2JqZWN0U3RhY2spO1xuICAgICAgaWYgKGlzRGVmKHZhbHVlKSkge1xuICAgICAgICB2YXIgYXJyYXkgPSBvYmplY3RTdGFja1tvYmplY3RTdGFjay5sZW5ndGggLSAxXTtcbiAgICAgICAgYXJyYXkucHVzaCh2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7T2JqZWN0fSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QgT2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3QuPFN0cmluZywgT2JqZWN0LjxTdHJpbmcsIEZ1bmN0aW9uPj59IHBhcnNlcnNOUyBQYXJzZXJzIGJ5IG5hbWVzcGFjZS5cbiAqIEBwYXJhbSB7Tm9kZX0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlIE5vZGUuXG4gKiBAcGFyYW0ge0FycmF5LjwqPn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0U3RhY2sgT2JqZWN0IHN0YWNrLlxuICogQHBhcmFtIHsqPX0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmQgVGhlIG9iamVjdCB0byB1c2UgYXMgYHRoaXNgLlxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gT2JqZWN0LlxuICovXG5YTUxQYXJzZXIucHVzaFBhcnNlQW5kUG9wID0gZnVuY3Rpb24ob2JqZWN0LCBwYXJzZXJzTlMsIG5vZGUsIG9iamVjdFN0YWNrLCBiaW5kKSB7XG4gIG9iamVjdFN0YWNrLnB1c2gob2JqZWN0KTtcbiAgWE1MUGFyc2VyLnBhcnNlTm9kZShwYXJzZXJzTlMsIG5vZGUsIG9iamVjdFN0YWNrLCBiaW5kKTtcbiAgcmV0dXJuIG9iamVjdFN0YWNrLnBvcCgpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBYTUxQYXJzZXI7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGlzRGVmID0gcmVxdWlyZSgnLi91dGlscy9pc2RlZicpO1xudmFyIHN0cmluZyA9IHJlcXVpcmUoJy4vdXRpbHMvc3RyaW5nJyk7XG52YXIgWE1MUGFyc2VyID0gcmVxdWlyZSgnLi94bWxfcGFyc2VyJyk7XG5cbnZhciBYU0QgPSB7fTtcblxuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblhTRC5OQU1FU1BBQ0VfVVJJID0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hJztcblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZS5cbiAqIEByZXR1cm4ge2Jvb2xlYW58dW5kZWZpbmVkfSBCb29sZWFuLlxuICovXG5YU0QucmVhZEJvb2xlYW4gPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBzID0gWE1MUGFyc2VyLmdldEFsbFRleHRDb250ZW50KG5vZGUsIGZhbHNlKTtcbiAgcmV0dXJuIFhTRC5yZWFkQm9vbGVhblN0cmluZyhzKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTdHJpbmcuXG4gKiBAcmV0dXJuIHtib29sZWFufHVuZGVmaW5lZH0gQm9vbGVhbi5cbiAqL1xuWFNELnJlYWRCb29sZWFuU3RyaW5nID0gZnVuY3Rpb24oc3RyaW5nKSB7XG4gIHZhciBtID0gL15cXHMqKHRydWV8MSl8KGZhbHNlfDApXFxzKiQvLmV4ZWMoc3RyaW5nKTtcbiAgaWYgKG0pIHtcbiAgICByZXR1cm4gaXNEZWYobVsxXSkgfHwgZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gRGF0ZVRpbWUgaW4gc2Vjb25kcy5cbiAqL1xuWFNELnJlYWREYXRlVGltZSA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIHMgPSBYTUxQYXJzZXIuZ2V0QWxsVGV4dENvbnRlbnQobm9kZSwgZmFsc2UpO1xuICB2YXIgcmUgPSAvXlxccyooXFxkezR9KS0oXFxkezJ9KS0oXFxkezJ9KVQoXFxkezJ9KTooXFxkezJ9KTooXFxkezJ9KShafCg/OihbK1xcLV0pKFxcZHsyfSkoPzo6KFxcZHsyfSkpPykpXFxzKiQvO1xuICB2YXIgbSA9IHJlLmV4ZWMocyk7XG4gIGlmIChtKSB7XG4gICAgdmFyIHllYXIgPSBwYXJzZUludChtWzFdLCAxMCk7XG4gICAgdmFyIG1vbnRoID0gcGFyc2VJbnQobVsyXSwgMTApIC0gMTtcbiAgICB2YXIgZGF5ID0gcGFyc2VJbnQobVszXSwgMTApO1xuICAgIHZhciBob3VyID0gcGFyc2VJbnQobVs0XSwgMTApO1xuICAgIHZhciBtaW51dGUgPSBwYXJzZUludChtWzVdLCAxMCk7XG4gICAgdmFyIHNlY29uZCA9IHBhcnNlSW50KG1bNl0sIDEwKTtcbiAgICB2YXIgZGF0ZVRpbWUgPSBEYXRlLlVUQyh5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCkgLyAxMDAwO1xuICAgIGlmIChtWzddICE9ICdaJykge1xuICAgICAgdmFyIHNpZ24gPSBtWzhdID09ICctJyA/IC0xIDogMTtcbiAgICAgIGRhdGVUaW1lICs9IHNpZ24gKiA2MCAqIHBhcnNlSW50KG1bOV0sIDEwKTtcbiAgICAgIGlmIChpc0RlZihtWzEwXSkpIHtcbiAgICAgICAgZGF0ZVRpbWUgKz0gc2lnbiAqIDYwICogNjAgKiBwYXJzZUludChtWzEwXSwgMTApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGF0ZVRpbWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gRGVjaW1hbC5cbiAqL1xuWFNELnJlYWREZWNpbWFsID0gZnVuY3Rpb24obm9kZSkge1xuICB2YXIgcyA9IFhNTFBhcnNlci5nZXRBbGxUZXh0Q29udGVudChub2RlLCBmYWxzZSk7XG4gIHJldHVybiBYU0QucmVhZERlY2ltYWxTdHJpbmcocyk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTdHJpbmcuXG4gKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBEZWNpbWFsLlxuICovXG5YU0QucmVhZERlY2ltYWxTdHJpbmcgPSBmdW5jdGlvbihzdHJpbmcpIHtcbiAgLy8gRklYTUUgY2hlY2sgc3BlY1xuICB2YXIgbSA9IC9eXFxzKihbK1xcLV0/XFxkKlxcLj9cXGQrKD86ZVsrXFwtXT9cXGQrKT8pXFxzKiQvaS5leGVjKHN0cmluZyk7XG4gIGlmIChtKSB7XG4gICAgcmV0dXJuIHBhcnNlRmxvYXQobVsxXSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlLlxuICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gTm9uIG5lZ2F0aXZlIGludGVnZXIuXG4gKi9cblhTRC5yZWFkTm9uTmVnYXRpdmVJbnRlZ2VyID0gZnVuY3Rpb24obm9kZSkge1xuICB2YXIgcyA9IFhNTFBhcnNlci5nZXRBbGxUZXh0Q29udGVudChub2RlLCBmYWxzZSk7XG4gIHJldHVybiBYU0QucmVhZE5vbk5lZ2F0aXZlSW50ZWdlclN0cmluZyhzKTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFN0cmluZy5cbiAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IE5vbiBuZWdhdGl2ZSBpbnRlZ2VyLlxuICovXG5YU0QucmVhZE5vbk5lZ2F0aXZlSW50ZWdlclN0cmluZyA9IGZ1bmN0aW9uKHN0cmluZykge1xuICB2YXIgbSA9IC9eXFxzKihcXGQrKVxccyokLy5leGVjKHN0cmluZyk7XG4gIGlmIChtKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KG1bMV0sIDEwKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIE5vZGUuXG4gKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBTdHJpbmcuXG4gKi9cblhTRC5yZWFkU3RyaW5nID0gZnVuY3Rpb24obm9kZSkge1xuICB2YXIgcyA9IFhNTFBhcnNlci5nZXRBbGxUZXh0Q29udGVudChub2RlLCBmYWxzZSk7XG4gIHJldHVybiBzdHJpbmcudHJpbShzKTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZSB0byBhcHBlbmQgYSBUZXh0Tm9kZSB3aXRoIHRoZSBib29sZWFuIHRvLlxuICogQHBhcmFtIHtib29sZWFufSBib29sIEJvb2xlYW4uXG4gKi9cblhTRC53cml0ZUJvb2xlYW5UZXh0Tm9kZSA9IGZ1bmN0aW9uKG5vZGUsIGJvb2wpIHtcbiAgWFNELndyaXRlU3RyaW5nVGV4dE5vZGUobm9kZSwgKGJvb2wpID8gJzEnIDogJzAnKTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgTm9kZSB0byBhcHBlbmQgYSBUZXh0Tm9kZSB3aXRoIHRoZSBkYXRlVGltZSB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkYXRlVGltZSBEYXRlVGltZSBpbiBzZWNvbmRzLlxuICovXG5YU0Qud3JpdGVEYXRlVGltZVRleHROb2RlID0gZnVuY3Rpb24obm9kZSwgZGF0ZVRpbWUpIHtcbiAgdmFyIGRhdGUgPSBuZXcgRGF0ZShkYXRlVGltZSAqIDEwMDApO1xuICB2YXIgc3RyaW5nID0gZGF0ZS5nZXRVVENGdWxsWWVhcigpICsgJy0nICtcbiAgICBzdHJpbmcucGFkTnVtYmVyKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEsIDIpICsgJy0nICtcbiAgICBzdHJpbmcucGFkTnVtYmVyKGRhdGUuZ2V0VVRDRGF0ZSgpLCAyKSArICdUJyArXG4gICAgc3RyaW5nLnBhZE51bWJlcihkYXRlLmdldFVUQ0hvdXJzKCksIDIpICsgJzonICtcbiAgICBzdHJpbmcucGFkTnVtYmVyKGRhdGUuZ2V0VVRDTWludXRlcygpLCAyKSArICc6JyArXG4gICAgc3RyaW5nLnBhZE51bWJlcihkYXRlLmdldFVUQ1NlY29uZHMoKSwgMikgKyAnWic7XG4gIG5vZGUuYXBwZW5kQ2hpbGQoWE1MUGFyc2VyLkRPQ1VNRU5ULmNyZWF0ZVRleHROb2RlKHN0cmluZykpO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlIHRvIGFwcGVuZCBhIFRleHROb2RlIHdpdGggdGhlIGRlY2ltYWwgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gZGVjaW1hbCBEZWNpbWFsLlxuICovXG5YU0Qud3JpdGVEZWNpbWFsVGV4dE5vZGUgPSBmdW5jdGlvbihub2RlLCBkZWNpbWFsKSB7XG4gIHZhciBzdHJpbmcgPSBkZWNpbWFsLnRvUHJlY2lzaW9uKCk7XG4gIG5vZGUuYXBwZW5kQ2hpbGQoWE1MUGFyc2VyLkRPQ1VNRU5ULmNyZWF0ZVRleHROb2RlKHN0cmluZykpO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlIHRvIGFwcGVuZCBhIFRleHROb2RlIHdpdGggdGhlIGRlY2ltYWwgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gbm9uTmVnYXRpdmVJbnRlZ2VyIE5vbiBuZWdhdGl2ZSBpbnRlZ2VyLlxuICovXG5YU0Qud3JpdGVOb25OZWdhdGl2ZUludGVnZXJUZXh0Tm9kZSA9IGZ1bmN0aW9uKG5vZGUsIG5vbk5lZ2F0aXZlSW50ZWdlcikge1xuICB2YXIgc3RyaW5nID0gbm9uTmVnYXRpdmVJbnRlZ2VyLnRvU3RyaW5nKCk7XG4gIG5vZGUuYXBwZW5kQ2hpbGQoWE1MUGFyc2VyLkRPQ1VNRU5ULmNyZWF0ZVRleHROb2RlKHN0cmluZykpO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBOb2RlIHRvIGFwcGVuZCBhIFRleHROb2RlIHdpdGggdGhlIHN0cmluZyB0by5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nLlxuICovXG5YU0Qud3JpdGVTdHJpbmdUZXh0Tm9kZSA9IGZ1bmN0aW9uKG5vZGUsIHN0cmluZykge1xuICBub2RlLmFwcGVuZENoaWxkKFhNTFBhcnNlci5ET0NVTUVOVC5jcmVhdGVUZXh0Tm9kZShzdHJpbmcpKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gWFNEO1xuIl19 +},{}]},{},["/Users/w8r/Projects/wms-capabilities/example/js/app.js"]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiZGlzdC93bXMtY2FwYWJpbGl0aWVzLm1pbi5qcyIsImV4YW1wbGUvanMvYXBwLmpzIiwiZXhhbXBsZS9qcy9qc29uLWZvcm1hdC5qcyIsImV4YW1wbGUvanMveG1sLWZvcm1hdC5qcyIsIm5vZGVfbW9kdWxlcy9yZXF3ZXN0L3JlcXdlc3QuanMiLCJub2RlX21vZHVsZXMvc3Bpbi5qcy9zcGluLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZtQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIoZnVuY3Rpb24ocil7XCJvYmplY3RcIj09PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT09dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1yKCk6XCJmdW5jdGlvblwiPT09dHlwZW9mIGRlZmluZSYmZGVmaW5lLk5hP2RlZmluZShbXSxyKTooXCJ1bmRlZmluZWRcIiE9PXR5cGVvZiB3aW5kb3c/d2luZG93OlwidW5kZWZpbmVkXCIhPT10eXBlb2YgZ2xvYmFsP2dsb2JhbDpcInVuZGVmaW5lZFwiIT09dHlwZW9mIHNlbGY/c2VsZjp0aGlzKS5XTVNDYXBhYmlsaXRpZXM9cigpfSkoZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24gZyhoLGEsZSl7ZnVuY3Rpb24gZihjLG0pe2lmKCFhW2NdKXtpZighaFtjXSl7dmFyIGI9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighbSYmYilyZXR1cm4gYihjLCEwKTtpZihsKXJldHVybiBsKGMsITApO2I9RXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2MrXCInXCIpO3Rocm93IGIuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixiO31iPVxuYVtjXT17ZXhwb3J0czp7fX07aFtjXVswXS5jYWxsKGIuZXhwb3J0cyxmdW5jdGlvbihhKXt2YXIgYj1oW2NdWzFdW2FdO3JldHVybiBmKGI/YjphKX0sYixiLmV4cG9ydHMsZyxoLGEsZSl9cmV0dXJuIGFbY10uZXhwb3J0c31mb3IodmFyIGw9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxjPTA7YzxlLmxlbmd0aDtjKyspZihlW2NdKTtyZXR1cm4gZn0oezE6W2Z1bmN0aW9uKGcsaCl7aC5leHBvcnRzPWcoXCIuL3NyYy93bXNcIil9LHtcIi4vc3JjL3dtc1wiOjZ9XSwyOltmdW5jdGlvbihnLGgpe2guZXhwb3J0cz17dToxLEVhOjIsY2E6MyxOOjQsSmE6NSxJYTo2LE1hOjcsRmE6OCxzOjksSGE6MTAsR2E6MTEsTGE6MTJ9fSx7fV0sMzpbZnVuY3Rpb24oZyxoKXtoLmV4cG9ydHM9ZnVuY3Rpb24oYSl7cmV0dXJuIHZvaWQgMCE9PWF9fSx7fV0sNDpbZnVuY3Rpb24oZyxoKXtoLmV4cG9ydHM9ZnVuY3Rpb24oYSxlLGYpe3JldHVybiBlIGluIGE/YVtlXTphW2VdPWZ9fSx7fV0sXG41OltmdW5jdGlvbihnLGgpe3ZhciBhPWcoXCIuL2lzZGVmXCIpLGU9L15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nO2guZXhwb3J0cz17dHJpbTpmdW5jdGlvbihhKXtyZXR1cm4gYS5yZXBsYWNlKGUsXCJcIil9LG06ZnVuY3Rpb24oZSxnLGMpe2U9YShjKT9lLnRvRml4ZWQoYyk6U3RyaW5nKGUpO2M9ZS5pbmRleE9mKFwiLlwiKTstMT09YyYmKGM9ZS5sZW5ndGgpO3JldHVybiBBcnJheShNYXRoLm1heCgwLGctYykrMSkuam9pbihcIjBcIikrZX19fSx7XCIuL2lzZGVmXCI6M31dLDY6W2Z1bmN0aW9uKGcsaCl7ZnVuY3Rpb24gYShhKXt0aGlzLnZlcnNpb249dm9pZCAwO3RoaXMudj1uZXcgZTt0aGlzLkY9YX12YXIgZT1nKFwiLi94bWxfcGFyc2VyXCIpLGY9ZyhcIi4vdXRpbHMvaXNkZWZcIiksbD1nKFwiLi9ub2RlX3R5cGVzXCIpLGM9ZyhcIi4vdXRpbHMvc2V0aWZ1bmRlZmluZWRcIiksZD1nKFwiLi94c2RcIiksbT1nKFwiLi94bGlua1wiKSxiPWUueWE7YS5wcm90b3R5cGUuZGF0YT1mdW5jdGlvbihhKXt0aGlzLkY9XG5hO3JldHVybiB0aGlzfTthLnByb3RvdHlwZS50b0pTT049ZnVuY3Rpb24oYSl7YT1hfHx0aGlzLkY7cmV0dXJuIHRoaXMucGFyc2UoYSl9O2EucHJvdG90eXBlLnBhcnNlPWZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnBhKHRoaXMudi5DYShhKSl9O2EucHJvdG90eXBlLnBhPWZ1bmN0aW9uKGEpe2ZvcihhPWEuZmlyc3RDaGlsZDthO2E9YS5uZXh0U2libGluZylpZihhLm5vZGVUeXBlPT1sLnUpcmV0dXJuIHRoaXMuQmEoYSk7cmV0dXJuIG51bGx9O2EucHJvdG90eXBlLkJhPWZ1bmN0aW9uKGMpe3RoaXMudmVyc2lvbj1jLmdldEF0dHJpYnV0ZShcInZlcnNpb25cIik7cmV0dXJuIGUuYih7dmVyc2lvbjp0aGlzLnZlcnNpb259LGEuWixjLFtdKXx8bnVsbH07YS5kYT1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5MLGMsYil9O2EuRz1mdW5jdGlvbihhKXt2YXIgYz1kLm87cmV0dXJuW2MoYS5nZXRBdHRyaWJ1dGUoXCJtaW54XCIpKSxjKGEuZ2V0QXR0cmlidXRlKFwibWlueVwiKSksYyhhLmdldEF0dHJpYnV0ZShcIm1heHhcIikpLFxuYyhhLmdldEF0dHJpYnV0ZShcIm1heHlcIikpXX07YS5mYT1mdW5jdGlvbihjKXt2YXIgYj1hLkcoYyksZT1kLm8sZT1bZShjLmdldEF0dHJpYnV0ZShcInJlc3hcIikpLGUoYy5nZXRBdHRyaWJ1dGUoXCJyZXN5XCIpKV07cmV0dXJue2NyczpjLmdldEF0dHJpYnV0ZShcIkNSU1wiKXx8Yy5nZXRBdHRyaWJ1dGUoXCJTUlNcIiksZXh0ZW50OmIscmVzOmV9fTthLnJhPWZ1bmN0aW9uKGMpe2M9YS5HKGMpO3JldHVybiBmKGNbMF0pJiZmKGNbMV0pJiZmKGNbMl0pJiZmKGNbM10pP2M6dm9pZCAwfTthLnZhPWZ1bmN0aW9uKGEpe3ZhciBjPXBhcnNlRmxvYXQoYS5nZXRBdHRyaWJ1dGUoXCJtaW5cIikpO2E9cGFyc2VGbG9hdChhLmdldEF0dHJpYnV0ZShcIm1heFwiKSk7cmV0dXJue21pbjpjLG1heDphfX07YS5uYT1mdW5jdGlvbihjLGIpe3ZhciBkPWUuYih7fSxhLlUsYyxiKTtpZihmKGQpKXt2YXIgbT1kLndlc3RCb3VuZExvbmdpdHVkZSxrPWQuc291dGhCb3VuZExhdGl0dWRlLGc9ZC5lYXN0Qm91bmRMb25naXR1ZGUsXG5kPWQubm9ydGhCb3VuZExhdGl0dWRlO3JldHVybiBmKG0pJiZmKGspJiZmKGcpJiZmKGQpP1ttLGssZyxkXTp2b2lkIDB9fTthLmdhPWZ1bmN0aW9uKGMsYil7cmV0dXJuIGUuYih7fSxhLk0sYyxiKX07YS53YT1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5hYSxjLGIpfTthLmphPWZ1bmN0aW9uKGMsYil7cmV0dXJuIGUuYih7fSxhLlAsYyxiKX07YS5rYT1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5SLGMsYil9O2EuaWE9ZnVuY3Rpb24oYyxiKXtyZXR1cm4gZS5iKHt9LGEuTyxjLGIpfTthLm9hPWZ1bmN0aW9uKGMsYil7cmV0dXJuIGUuYihbXSxhLlQsYyxiKX07YS5oYT1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5ELGMsYil9O2Euc2E9ZnVuY3Rpb24oYixtKXt2YXIgZz1tW20ubGVuZ3RoLTFdLGg9ZS5iKHt9LGEuRCxiLG0pO2lmKGYoaCkpe3ZhciBrPWQuaShiLmdldEF0dHJpYnV0ZShcInF1ZXJ5YWJsZVwiKSk7ZihrKXx8KGs9Zy5xdWVyeWFibGUpO1xuaC5xdWVyeWFibGU9ZihrKT9rOiExO2s9ZC5DKGIuZ2V0QXR0cmlidXRlKFwiY2FzY2FkZWRcIikpO2Yoayl8fChrPWcuY2FzY2FkZWQpO2guY2FzY2FkZWQ9aztrPWQuaShiLmdldEF0dHJpYnV0ZShcIm9wYXF1ZVwiKSk7ZihrKXx8KGs9Zy5vcGFxdWUpO2gub3BhcXVlPWYoayk/azohMTtrPWQuaShiLmdldEF0dHJpYnV0ZShcIm5vU3Vic2V0c1wiKSk7ZihrKXx8KGs9Zy5ub1N1YnNldHMpO2gubm9TdWJzZXRzPWYoayk/azohMTtrPWQubyhiLmdldEF0dHJpYnV0ZShcImZpeGVkV2lkdGhcIikpO2Yoayl8fChrPWcuZml4ZWRXaWR0aCk7aC5maXhlZFdpZHRoPWs7az1kLm8oYi5nZXRBdHRyaWJ1dGUoXCJmaXhlZEhlaWdodFwiKSk7ZihrKXx8KGs9Zy5maXhlZEhlaWdodCk7aC5maXhlZEhlaWdodD1rO2Zvcih2YXIgbD1bXCJTdHlsZVwiLFwiQ1JTXCIsXCJBdXRob3JpdHlVUkxcIl0saz0wLHQ9bC5sZW5ndGg7azx0O2srKyl7dmFyIG49bFtrXSxxPWdbbl07aWYoZihxKSl7dmFyIHA9YyhoLG4sW10pLHA9cC5jb25jYXQocSk7XG5oW25dPXB9fWw9XCJFWF9HZW9ncmFwaGljQm91bmRpbmdCb3ggQm91bmRpbmdCb3ggRGltZW5zaW9uIEF0dHJpYnV0aW9uIE1pblNjYWxlRGVub21pbmF0b3IgTWF4U2NhbGVEZW5vbWluYXRvclwiLnNwbGl0KFwiIFwiKTtrPTA7Zm9yKHQ9bC5sZW5ndGg7azx0O2srKyluPWxba10scD1oW25dLGYocCl8fChxPWdbbl0saFtuXT1xKTtyZXR1cm4gaH19O2EubWE9ZnVuY3Rpb24oYSl7cmV0dXJue25hbWU6YS5nZXRBdHRyaWJ1dGUoXCJuYW1lXCIpLHVuaXRzOmEuZ2V0QXR0cmlidXRlKFwidW5pdHNcIiksdW5pdFN5bWJvbDphLmdldEF0dHJpYnV0ZShcInVuaXRTeW1ib2xcIiksXCJkZWZhdWx0XCI6YS5nZXRBdHRyaWJ1dGUoXCJkZWZhdWx0XCIpLG11bHRpcGxlVmFsdWVzOmQuaShhLmdldEF0dHJpYnV0ZShcIm11bHRpcGxlVmFsdWVzXCIpKSxuZWFyZXN0VmFsdWU6ZC5pKGEuZ2V0QXR0cmlidXRlKFwibmVhcmVzdFZhbHVlXCIpKSxjdXJyZW50OmQuaShhLmdldEF0dHJpYnV0ZShcImN1cnJlbnRcIikpLHZhbHVlczpkLmEoYSl9fTtcbmEuaD1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5WLGMsYil9O2EudWE9ZnVuY3Rpb24oYyxiKXtyZXR1cm4gZS5iKHt9LGEuJCxjLGIpfTthLmxhPWZ1bmN0aW9uKGMsYil7cmV0dXJuIGUuYih7fSxhLlMsYyxiKX07YS5xYT1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5XLGMsYil9O2Eudz1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5ZLGMsYil9O2EuST1mdW5jdGlvbihjLGIpe3ZhciBlPWEuaChjLGIpO2lmKGYoZSkpe3ZhciBtPWQuQyxtPVttKGMuZ2V0QXR0cmlidXRlKFwid2lkdGhcIikpLG0oYy5nZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIikpXTtlLnNpemU9bTtyZXR1cm4gZX19O2EuZWE9ZnVuY3Rpb24oYyxiKXt2YXIgZD1hLmgoYyxiKTtpZihmKGQpKXJldHVybiBkLm5hbWU9Yy5nZXRBdHRyaWJ1dGUoXCJuYW1lXCIpLGR9O2EudGE9ZnVuY3Rpb24oYyxiKXt2YXIgZD1hLmgoYyxiKTtpZihmKGQpKXJldHVybiBkLnR5cGU9Yy5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpLFxuZH07YS54YT1mdW5jdGlvbihjLGIpe3JldHVybiBlLmIoe30sYS5iYSxjLGIpfTthLkg9ZnVuY3Rpb24oYyxiKXtyZXR1cm4gZS5iKFtdLGEuWCxjLGIpfTthLmM9W251bGwsXCJodHRwOi8vd3d3Lm9wZW5naXMubmV0L3dtc1wiXTthLlo9ZS5mKGEuYyx7U2VydmljZTpiKGEud2EpLENhcGFiaWxpdHk6YihhLmdhKX0pO2EuTT1lLmYoYS5jLHtSZXF1ZXN0OmIoYS51YSksRXhjZXB0aW9uOmIoYS5vYSksTGF5ZXI6YihhLmhhKX0pO2EuYWE9ZS5mKGEuYyx7TmFtZTpiKGQuYSksVGl0bGU6YihkLmEpLEFic3RyYWN0OmIoZC5hKSxLZXl3b3JkTGlzdDpiKGEuSCksT25saW5lUmVzb3VyY2U6YihtLkEpLENvbnRhY3RJbmZvcm1hdGlvbjpiKGEuamEpLEZlZXM6YihkLmEpLEFjY2Vzc0NvbnN0cmFpbnRzOmIoZC5hKSxMYXllckxpbWl0OmIoZC5CKSxNYXhXaWR0aDpiKGQuQiksTWF4SGVpZ2h0OmIoZC5CKX0pO2EuUD1lLmYoYS5jLHtDb250YWN0UGVyc29uUHJpbWFyeTpiKGEua2EpLENvbnRhY3RQb3NpdGlvbjpiKGQuYSksXG5Db250YWN0QWRkcmVzczpiKGEuaWEpLENvbnRhY3RWb2ljZVRlbGVwaG9uZTpiKGQuYSksQ29udGFjdEZhY3NpbWlsZVRlbGVwaG9uZTpiKGQuYSksQ29udGFjdEVsZWN0cm9uaWNNYWlsQWRkcmVzczpiKGQuYSl9KTthLlI9ZS5mKGEuYyx7Q29udGFjdFBlcnNvbjpiKGQuYSksQ29udGFjdE9yZ2FuaXphdGlvbjpiKGQuYSl9KTthLk89ZS5mKGEuYyx7QWRkcmVzc1R5cGU6YihkLmEpLEFkZHJlc3M6YihkLmEpLENpdHk6YihkLmEpLFN0YXRlT3JQcm92aW5jZTpiKGQuYSksUG9zdENvZGU6YihkLmEpLENvdW50cnk6YihkLmEpfSk7YS5UPWUuZihhLmMse0Zvcm1hdDplLksoZC5hKX0pO2EuRD1lLmYoYS5jLHtOYW1lOmIoZC5hKSxUaXRsZTpiKGQuYSksQWJzdHJhY3Q6YihkLmEpLEtleXdvcmRMaXN0OmIoYS5IKSxDUlM6ZS5nKGQuYSksU1JTOmUuZyhkLmEpLEVYX0dlb2dyYXBoaWNCb3VuZGluZ0JveDpiKGEubmEpLExhdExvbkJvdW5kaW5nQm94OmIoYS5yYSksQm91bmRpbmdCb3g6ZS5nKGEuZmEpLFxuRGltZW5zaW9uOmUuZyhhLm1hKSxBdHRyaWJ1dGlvbjpiKGEuZGEpLEF1dGhvcml0eVVSTDplLmcoYS5lYSksSWRlbnRpZmllcjplLmcoZC5hKSxNZXRhZGF0YVVSTDplLmcoYS50YSksRGF0YVVSTDplLmcoYS5oKSxGZWF0dXJlTGlzdFVSTDplLmcoYS5oKSxTdHlsZTplLmcoYS54YSksTWluU2NhbGVEZW5vbWluYXRvcjpiKGQuaiksTWF4U2NhbGVEZW5vbWluYXRvcjpiKGQuaiksU2NhbGVIaW50OmIoYS52YSksTGF5ZXI6ZS5nKGEuc2EpfSk7YS5MPWUuZihhLmMse1RpdGxlOmIoZC5hKSxPbmxpbmVSZXNvdXJjZTpiKG0uQSksTG9nb1VSTDpiKGEuSSl9KTthLlU9ZS5mKGEuYyx7d2VzdEJvdW5kTG9uZ2l0dWRlOmIoZC5qKSxlYXN0Qm91bmRMb25naXR1ZGU6YihkLmopLHNvdXRoQm91bmRMYXRpdHVkZTpiKGQuaiksbm9ydGhCb3VuZExhdGl0dWRlOmIoZC5qKX0pO2EuJD1lLmYoYS5jLHtHZXRDYXBhYmlsaXRpZXM6YihhLncpLEdldE1hcDpiKGEudyksR2V0RmVhdHVyZUluZm86YihhLncpfSk7XG5hLlk9ZS5mKGEuYyx7Rm9ybWF0OmUuZyhkLmEpLERDUFR5cGU6ZS5nKGEubGEpfSk7YS5TPWUuZihhLmMse0hUVFA6YihhLnFhKX0pO2EuVz1lLmYoYS5jLHtHZXQ6YihhLmgpLFBvc3Q6YihhLmgpfSk7YS5iYT1lLmYoYS5jLHtOYW1lOmIoZC5hKSxUaXRsZTpiKGQuYSksQWJzdHJhY3Q6YihkLmEpLExlZ2VuZFVSTDplLmcoYS5JKSxTdHlsZVNoZWV0VVJMOmIoYS5oKSxTdHlsZVVSTDpiKGEuaCl9KTthLlY9ZS5mKGEuYyx7Rm9ybWF0OmIoZC5hKSxPbmxpbmVSZXNvdXJjZTpiKG0uQSl9KTthLlg9ZS5mKGEuYyx7S2V5d29yZDplLksoZC5hKX0pO2guZXhwb3J0cz1hfSx7XCIuL25vZGVfdHlwZXNcIjoyLFwiLi91dGlscy9pc2RlZlwiOjMsXCIuL3V0aWxzL3NldGlmdW5kZWZpbmVkXCI6NCxcIi4veGxpbmtcIjo3LFwiLi94bWxfcGFyc2VyXCI6OCxcIi4veHNkXCI6OX1dLDc6W2Z1bmN0aW9uKGcsaCl7aC5leHBvcnRzPXtBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmdldEF0dHJpYnV0ZU5TKFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiLFxuXCJocmVmXCIpfX19LHt9XSw4OltmdW5jdGlvbihnLGgpe2Z1bmN0aW9uIGEoKXt0aGlzLnY9bmV3IERPTVBhcnNlcn12YXIgZT1nKFwiLi91dGlscy9pc2RlZlwiKSxmPWcoXCIuL3V0aWxzL3NldGlmdW5kZWZpbmVkXCIpLGw9ZyhcIi4vbm9kZV90eXBlc1wiKTthLnByb3RvdHlwZS5DYT1mdW5jdGlvbihhKXtyZXR1cm4gdGhpcy52LnBhcnNlRnJvbVN0cmluZyhhLFwiYXBwbGljYXRpb24veG1sXCIpfTthLmw9ZnVuY3Rpb24oYyl7cmV0dXJuIGEuSihjLCExLFtdKS5qb2luKFwiXCIpfTthLko9ZnVuY3Rpb24oYyxkLGUpe2lmKGMubm9kZVR5cGU9PT1sLk58fGMubm9kZVR5cGU9PT1sLmNhKWQ/ZS5wdXNoKFN0cmluZyhjLm5vZGVWYWx1ZSkucmVwbGFjZSgvKFxcclxcbnxcXHJ8XFxuKS9nLFwiXCIpKTplLnB1c2goYy5ub2RlVmFsdWUpO2Vsc2UgZm9yKGM9Yy5maXJzdENoaWxkO2M7Yz1jLm5leHRTaWJsaW5nKWEuSihjLGQsZSk7cmV0dXJuIGV9O2EuQWE9ZnVuY3Rpb24oYyxkLG0pe2ZvcihkPWEuZmlyc3RFbGVtZW50Q2hpbGQoZCk7ZDtkPVxuYS5uZXh0RWxlbWVudFNpYmxpbmcoZCkpe3ZhciBiPWNbZC5uYW1lc3BhY2VVUkl8fG51bGxdO2UoYikmJihiPWJbZC5sb2NhbE5hbWVdLGUoYikmJmIuY2FsbCh2b2lkIDAsZCxtKSl9fTthLmZpcnN0RWxlbWVudENoaWxkPWZ1bmN0aW9uKGEpe2ZvcihhPWEuZmlyc3RFbGVtZW50Q2hpbGR8fGEuZmlyc3RDaGlsZDthJiZhLm5vZGVUeXBlIT09bC51OylhPWEubmV4dFNpYmxpbmc7cmV0dXJuIGF9O2EubmV4dEVsZW1lbnRTaWJsaW5nPWZ1bmN0aW9uKGEpe2ZvcihhPWEubmV4dEVsZW1lbnRTaWJsaW5nfHxhLm5leHRTaWJsaW5nO2EmJmEubm9kZVR5cGUhPT1sLnU7KWE9YS5uZXh0U2libGluZztyZXR1cm4gYX07YS5mPWZ1bmN0aW9uKGMsZCl7cmV0dXJuIGEuemEoYyxkKX07YS56YT1mdW5jdGlvbihhLGQpe3ZhciBtPWUodm9pZCAwKT92b2lkIDA6e30sYixmO2I9MDtmb3IoZj1hLmxlbmd0aDtiPGY7KytiKW1bYVtiXV09ZDtyZXR1cm4gbX07YS55YT1mdW5jdGlvbihhLGQsZil7cmV0dXJuIGZ1bmN0aW9uKGIsXG5nKXt2YXIgaD1hLmNhbGwoZShmKT9mOnRoaXMsYixnKTtpZihlKGgpKXt2YXIgbD1nW2cubGVuZ3RoLTFdLHU9ZShkKT9kOmIubG9jYWxOYW1lO2xbdV09aH19fTthLmc9ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKGQsZyl7dmFyIGI9YS5jYWxsKGUodm9pZCAwKT92b2lkIDA6dGhpcyxkLGcpO2lmKGUoYikpe3ZhciBoPWdbZy5sZW5ndGgtMV0sbD1lKHZvaWQgMCk/dm9pZCAwOmQubG9jYWxOYW1lO2YoaCxsLFtdKS5wdXNoKGIpfX19O2EuSz1mdW5jdGlvbihhKXtyZXR1cm4gZnVuY3Rpb24oZCxmKXt2YXIgYj1hLmNhbGwoZSh2b2lkIDApP3ZvaWQgMDp0aGlzLGQsZik7ZShiKSYmZltmLmxlbmd0aC0xXS5wdXNoKGIpfX07YS5iPWZ1bmN0aW9uKGMsZCxlLGIpe2IucHVzaChjKTthLkFhKGQsZSxiKTtyZXR1cm4gYi5wb3AoKX07aC5leHBvcnRzPWF9LHtcIi4vbm9kZV90eXBlc1wiOjIsXCIuL3V0aWxzL2lzZGVmXCI6MyxcIi4vdXRpbHMvc2V0aWZ1bmRlZmluZWRcIjo0fV0sOTpbZnVuY3Rpb24oZyxcbmgpe3ZhciBhPWcoXCIuL3V0aWxzL2lzZGVmXCIpLGU9ZyhcIi4vdXRpbHMvc3RyaW5nXCIpLGY9ZyhcIi4veG1sX3BhcnNlclwiKSxsPXtLYTpcImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hXCIsT2E6ZnVuY3Rpb24oYSl7YT1mLmwoYSk7cmV0dXJuIGwuaShhKX0saTpmdW5jdGlvbihjKXtpZihjPS9eXFxzKih0cnVlfDEpfChmYWxzZXwwKVxccyokLy5leGVjKGMpKXJldHVybiBhKGNbMV0pfHwhMX0sUGE6ZnVuY3Rpb24oYyl7Yz1mLmwoYyk7aWYoYz0vXlxccyooXFxkezR9KS0oXFxkezJ9KS0oXFxkezJ9KVQoXFxkezJ9KTooXFxkezJ9KTooXFxkezJ9KShafCg/OihbK1xcLV0pKFxcZHsyfSkoPzo6KFxcZHsyfSkpPykpXFxzKiQvLmV4ZWMoYykpe3ZhciBkPURhdGUuVVRDKHBhcnNlSW50KGNbMV0sMTApLHBhcnNlSW50KGNbMl0sMTApLTEscGFyc2VJbnQoY1szXSwxMCkscGFyc2VJbnQoY1s0XSwxMCkscGFyc2VJbnQoY1s1XSwxMCkscGFyc2VJbnQoY1s2XSwxMCkpLzFFMztpZihcIlpcIiE9Y1s3XSl7dmFyIGU9XG5cIi1cIj09Y1s4XT8tMToxLGQ9ZCs2MCplKnBhcnNlSW50KGNbOV0sMTApO2EoY1sxMF0pJiYoZCs9MzYwMCplKnBhcnNlSW50KGNbMTBdLDEwKSl9cmV0dXJuIGR9fSxqOmZ1bmN0aW9uKGEpe2E9Zi5sKGEpO3JldHVybiBsLm8oYSl9LG86ZnVuY3Rpb24oYSl7aWYoYT0vXlxccyooWytcXC1dP1xcZCpcXC4/XFxkKyg/OmVbK1xcLV0/XFxkKyk/KVxccyokL2kuZXhlYyhhKSlyZXR1cm4gcGFyc2VGbG9hdChhWzFdKX0sQjpmdW5jdGlvbihhKXthPWYubChhKTtyZXR1cm4gbC5DKGEpfSxDOmZ1bmN0aW9uKGEpe2lmKGE9L15cXHMqKFxcZCspXFxzKiQvLmV4ZWMoYSkpcmV0dXJuIHBhcnNlSW50KGFbMV0sMTApfSxhOmZ1bmN0aW9uKGEpe2E9Zi5sKGEpO3JldHVybiBlLnRyaW0oYSl9LFFhOmZ1bmN0aW9uKGEsZCl7bC5EYShhLGQ/XCIxXCI6XCIwXCIpfSxSYTpmdW5jdGlvbihhLGQpe3ZhciBlPW5ldyBEYXRlKDFFMypkKSxiPWUuZ2V0VVRDRnVsbFllYXIoKStcIi1cIitiLm0oZS5nZXRVVENNb250aCgpKzEsMikrXG5cIi1cIitiLm0oZS5nZXRVVENEYXRlKCksMikrXCJUXCIrYi5tKGUuZ2V0VVRDSG91cnMoKSwyKStcIjpcIitiLm0oZS5nZXRVVENNaW51dGVzKCksMikrXCI6XCIrYi5tKGUuZ2V0VVRDU2Vjb25kcygpLDIpK1wiWlwiO2EuYXBwZW5kQ2hpbGQoZi5zLmNyZWF0ZVRleHROb2RlKGIpKX0sU2E6ZnVuY3Rpb24oYSxkKXthLmFwcGVuZENoaWxkKGYucy5jcmVhdGVUZXh0Tm9kZShkLnRvUHJlY2lzaW9uKCkpKX0sVGE6ZnVuY3Rpb24oYSxkKXthLmFwcGVuZENoaWxkKGYucy5jcmVhdGVUZXh0Tm9kZShkLnRvU3RyaW5nKCkpKX0sRGE6ZnVuY3Rpb24oYSxkKXthLmFwcGVuZENoaWxkKGYucy5jcmVhdGVUZXh0Tm9kZShkKSl9fTtoLmV4cG9ydHM9bH0se1wiLi91dGlscy9pc2RlZlwiOjMsXCIuL3V0aWxzL3N0cmluZ1wiOjUsXCIuL3htbF9wYXJzZXJcIjo4fV19LHt9LFsxXSkoMSl9KTtcbiIsInZhciBqc29uRm9ybWF0ID0gZ2xvYmFsLmpzb25Gb3JtYXQgPSByZXF1aXJlKCcuL2pzb24tZm9ybWF0Jyk7XG52YXIgeG1sRm9ybWF0ID0gZ2xvYmFsLnhtbEZvcm1hdCA9IHJlcXVpcmUoJy4veG1sLWZvcm1hdCcpO1xudmFyIFdNU0NhcGFiaWxpdGllcyA9IGdsb2JhbC5XTVNDYXBhYmlsaXRpZXMgfHwgcmVxdWlyZSgnLi4vLi4vZGlzdC93bXMtY2FwYWJpbGl0aWVzLm1pbicpO1xudmFyIFNwaW5uZXIgPSByZXF1aXJlKCdzcGluLmpzJyk7XG52YXIgcmVxd2VzdCA9IGdsb2JhbC5yZXF3ZXN0ID0gcmVxdWlyZSgncmVxd2VzdCcpO1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xudmFyIHNlcnZpY2VTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VydmljZScpO1xudmFyIHhtbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd4bWwnKTtcbnZhciBqc29uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2pzb24nKTtcbnZhciBpbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdpbnB1dC1hcmVhJyk7XG5cbi8vIHRoZSBvbmx5IG9wZW4gQ09SUyBwcm94eSBJIGNvdWxkIGZpbmRcbnZhciBwcm94eSA9IFwiaHR0cHM6Ly9xdWVyeS55YWhvb2FwaXMuY29tL3YxL3B1YmxpYy95cWxcIjtcbnZhciBwYXJzZXIgPSBuZXcgV01TQ2FwYWJpbGl0aWVzKCk7XG5cbmZ1bmN0aW9uIHNob3dJbnB1dCgpIHtcbiAgeG1sLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIGlucHV0LnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcbn1cblxuZnVuY3Rpb24gaGlkZUlucHV0KCkge1xuICB4bWwuc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUtYmxvY2snO1xuICBpbnB1dC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xufVxuXG5mdW5jdGlvbiB1cGRhdGUoeG1sU3RyaW5nKSB7XG4gIHhtbC50ZXh0Q29udGVudCA9IHhtbEZvcm1hdCh4bWxTdHJpbmcpO1xuICBQcmlzbS5oaWdobGlnaHRFbGVtZW50KHhtbCk7XG5cbiAganNvbi50ZXh0Q29udGVudCA9IGpzb25Gb3JtYXQoSlNPTi5zdHJpbmdpZnkocGFyc2VyLnBhcnNlKHhtbFN0cmluZykpKTtcbiAgUHJpc20uaGlnaGxpZ2h0RWxlbWVudChqc29uKTtcbn1cblxuc2VydmljZVNlbGVjdC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHtcbiAgaWYgKHNlcnZpY2VTZWxlY3QudmFsdWUgIT09ICcnKSB7XG4gICAgaGlkZUlucHV0KCk7XG5cbiAgICByZXF3ZXN0KHtcbiAgICAgIHVybDogcHJveHksXG4gICAgICBkYXRhOiB7XG4gICAgICAgIHE6ICdzZWxlY3QgKiBmcm9tIHhtbCB3aGVyZSB1cmw9XCInICtcbiAgICAgICAgICBzZXJ2aWNlU2VsZWN0LnZhbHVlLnJlcGxhY2UoL1xcJmFtcFxcOy9nLCAnJicpICsgJ1wiJ1xuICAgICAgfSxcbiAgICAgIHR5cGU6IFwieG1sXCIsXG4gICAgICBjcm9zc09yaWdpbjogdHJ1ZSxcbiAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uKHhtbCkge1xuICAgICAgICB1cGRhdGUoeG1sLmZpcnN0Q2hpbGQuZmlyc3RDaGlsZC5pbm5lckhUTUwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59LCBmYWxzZSk7XG5cbnhtbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHNob3dJbnB1dCwgZmFsc2UpO1xuXG5pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdwYXN0ZScsIGZ1bmN0aW9uKCkge1xuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIHVwZGF0ZShpbnB1dC52YWx1ZSk7XG4gICAgaGlkZUlucHV0KCk7XG4gIH0sIDUwKTtcbn0sIGZhbHNlKTtcbiIsIi8qXG4gICAganNvbi1mb3JtYXQgdi4xLjFcbiAgICBodHRwOi8vZ2l0aHViLmNvbS9waG9ib3NsYWIvanNvbi1mb3JtYXRcblxuICAgIFJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlOlxuICAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG4qL1xuXG52YXIgcCA9IFtdLFxuICBwdXNoID0gZnVuY3Rpb24obSkge1xuICAgIHJldHVybiAnXFxcXCcgKyBwLnB1c2gobSkgKyAnXFxcXCc7XG4gIH0sXG4gIHBvcCA9IGZ1bmN0aW9uKG0sIGkpIHtcbiAgICByZXR1cm4gcFtpIC0gMV1cbiAgfSxcbiAgdGFicyA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgcmV0dXJuIG5ldyBBcnJheShjb3VudCArIDEpLmpvaW4oJ1xcdCcpO1xuICB9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGpzb24pIHtcbiAgcCA9IFtdO1xuICB2YXIgb3V0ID0gXCJcIixcbiAgICBpbmRlbnQgPSAwO1xuXG4gIC8vIEV4dHJhY3QgYmFja3NsYXNoZXMgYW5kIHN0cmluZ3NcbiAganNvbiA9IGpzb25cbiAgICAucmVwbGFjZSgvXFxcXC4vZywgcHVzaClcbiAgICAucmVwbGFjZSgvKFwiLio/XCJ8Jy4qPycpL2csIHB1c2gpXG4gICAgLnJlcGxhY2UoL1xccysvLCAnJyk7XG5cbiAgLy8gSW5kZW50IGFuZCBpbnNlcnQgbmV3bGluZXNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBqc29uLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGMgPSBqc29uLmNoYXJBdChpKTtcblxuICAgIHN3aXRjaCAoYykge1xuICAgICAgY2FzZSAneyc6XG4gICAgICAgIG91dCArPSBjICsgXCJcXG5cIiArIHRhYnMoKytpbmRlbnQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1snOlxuICAgICAgICBvdXQgKz0gYyArIFwiXFxuXCIgKyB0YWJzKCsraW5kZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICddJzpcbiAgICAgICAgb3V0ICs9IFwiXFxuXCIgKyB0YWJzKC0taW5kZW50KSArIGM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnfSc6XG4gICAgICAgIG91dCArPSBcIlxcblwiICsgdGFicygtLWluZGVudCkgKyBjO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJywnOlxuICAgICAgICBpZiAoL1xcZC8udGVzdChqc29uLmNoYXJBdChpIC0gMSkpKSB7XG4gICAgICAgICAgb3V0ICs9IFwiLCBcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXQgKz0gXCIsXFxuXCIgKyB0YWJzKGluZGVudCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc6JzpcbiAgICAgICAgb3V0ICs9IFwiOiBcIjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBvdXQgKz0gYztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RyaXAgd2hpdGVzcGFjZSBmcm9tIG51bWVyaWMgYXJyYXlzIGFuZCBwdXQgYmFja3NsYXNoZXNcbiAgLy8gYW5kIHN0cmluZ3MgYmFjayBpblxuICBvdXQgPSBvdXRcbiAgICAucmVwbGFjZSgvXFxbW1xcZCxcXHNdKz9cXF0vZywgZnVuY3Rpb24obSkge1xuICAgICAgcmV0dXJuIG0ucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICB9KVxuICAgIC8vIG51bWJlciBhcnJheXNcbiAgICAucmVwbGFjZSgvXFxbXFxzKihcXGQpL2csIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIHJldHVybiAnWycgKyBiO1xuICAgIH0pXG4gICAgLnJlcGxhY2UoLyhcXGQpXFxzKlxcXS9nLCBmdW5jdGlvbihhLCBiKSB7XG4gICAgICByZXR1cm4gYiArICddJztcbiAgICB9KVxuICAgIC5yZXBsYWNlKC9cXHtcXHMqXFx9L2csICd7fScpIC8vIGVtcHR5IG9iamVjdHNcbiAgICAucmVwbGFjZSgvXFxcXChcXGQrKVxcXFwvZywgcG9wKSAvLyBzdHJpbmdzXG4gICAgLnJlcGxhY2UoL1xcXFwoXFxkKylcXFxcL2csIHBvcCk7IC8vIGJhY2tzbGFzaGVzIGluIHN0cmluZ3NcblxuICByZXR1cm4gb3V0O1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHhtbCkge1xuICB2YXIgZm9ybWF0dGVkID0gJyc7XG4gIHZhciByZWcgPSAvKD4pKDwpKFxcLyopL2c7XG4gIHhtbCA9IHhtbC5yZXBsYWNlKHJlZywgJyQxXFxyXFxuJDIkMycpO1xuICB2YXIgcGFkID0gMDtcblxuICB4bWwuc3BsaXQoJ1xcclxcbicpLmZvckVhY2goZnVuY3Rpb24obm9kZSwgaW5kZXgpIHtcbiAgICB2YXIgaW5kZW50ID0gMDtcbiAgICBpZiAobm9kZS5tYXRjaCgvLis8XFwvXFx3W14+XSo+JC8pKSB7XG4gICAgICBpbmRlbnQgPSAwO1xuICAgIH0gZWxzZSBpZiAobm9kZS5tYXRjaCgvXjxcXC9cXHcvKSkge1xuICAgICAgaWYgKHBhZCAhPSAwKSB7XG4gICAgICAgIHBhZCAtPSAxO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS5tYXRjaCgvXjxcXHdbXj5dKlteXFwvXT4uKiQvKSkge1xuICAgICAgaW5kZW50ID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5kZW50ID0gMDtcbiAgICB9XG5cbiAgICB2YXIgcGFkZGluZyA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFkOyBpKyspIHtcbiAgICAgIHBhZGRpbmcgKz0gJyAgJztcbiAgICB9XG5cbiAgICBmb3JtYXR0ZWQgKz0gcGFkZGluZyArIG5vZGUgKyAnXFxyXFxuJztcbiAgICBwYWQgKz0gaW5kZW50O1xuICB9KTtcblxuICByZXR1cm4gZm9ybWF0dGVkO1xufTtcbiIsIi8qIVxuICAqIFJlcXdlc3QhIEEgZ2VuZXJhbCBwdXJwb3NlIFhIUiBjb25uZWN0aW9uIG1hbmFnZXJcbiAgKiBsaWNlbnNlIE1JVCAoYykgRHVzdGluIERpYXogMjAxNFxuICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9kZWQvcmVxd2VzdFxuICAqL1xuXG4hZnVuY3Rpb24gKG5hbWUsIGNvbnRleHQsIGRlZmluaXRpb24pIHtcbiAgaWYgKHR5cGVvZiBtb2R1bGUgIT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIG1vZHVsZS5leHBvcnRzID0gZGVmaW5pdGlvbigpXG4gIGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSBkZWZpbmUoZGVmaW5pdGlvbilcbiAgZWxzZSBjb250ZXh0W25hbWVdID0gZGVmaW5pdGlvbigpXG59KCdyZXF3ZXN0JywgdGhpcywgZnVuY3Rpb24gKCkge1xuXG4gIHZhciB3aW4gPSB3aW5kb3dcbiAgICAsIGRvYyA9IGRvY3VtZW50XG4gICAgLCBodHRwc1JlID0gL15odHRwL1xuICAgICwgcHJvdG9jb2xSZSA9IC8oXlxcdyspOlxcL1xcLy9cbiAgICAsIHR3b0h1bmRvID0gL14oMjBcXGR8MTIyMykkLyAvL2h0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTAwNDY5NzIvbXNpZS1yZXR1cm5zLXN0YXR1cy1jb2RlLW9mLTEyMjMtZm9yLWFqYXgtcmVxdWVzdFxuICAgICwgYnlUYWcgPSAnZ2V0RWxlbWVudHNCeVRhZ05hbWUnXG4gICAgLCByZWFkeVN0YXRlID0gJ3JlYWR5U3RhdGUnXG4gICAgLCBjb250ZW50VHlwZSA9ICdDb250ZW50LVR5cGUnXG4gICAgLCByZXF1ZXN0ZWRXaXRoID0gJ1gtUmVxdWVzdGVkLVdpdGgnXG4gICAgLCBoZWFkID0gZG9jW2J5VGFnXSgnaGVhZCcpWzBdXG4gICAgLCB1bmlxaWQgPSAwXG4gICAgLCBjYWxsYmFja1ByZWZpeCA9ICdyZXF3ZXN0XycgKyAoK25ldyBEYXRlKCkpXG4gICAgLCBsYXN0VmFsdWUgLy8gZGF0YSBzdG9yZWQgYnkgdGhlIG1vc3QgcmVjZW50IEpTT05QIGNhbGxiYWNrXG4gICAgLCB4bWxIdHRwUmVxdWVzdCA9ICdYTUxIdHRwUmVxdWVzdCdcbiAgICAsIHhEb21haW5SZXF1ZXN0ID0gJ1hEb21haW5SZXF1ZXN0J1xuICAgICwgbm9vcCA9IGZ1bmN0aW9uICgpIHt9XG5cbiAgICAsIGlzQXJyYXkgPSB0eXBlb2YgQXJyYXkuaXNBcnJheSA9PSAnZnVuY3Rpb24nXG4gICAgICAgID8gQXJyYXkuaXNBcnJheVxuICAgICAgICA6IGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICByZXR1cm4gYSBpbnN0YW5jZW9mIEFycmF5XG4gICAgICAgICAgfVxuXG4gICAgLCBkZWZhdWx0SGVhZGVycyA9IHtcbiAgICAgICAgICAnY29udGVudFR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJ1xuICAgICAgICAsICdyZXF1ZXN0ZWRXaXRoJzogeG1sSHR0cFJlcXVlc3RcbiAgICAgICAgLCAnYWNjZXB0Jzoge1xuICAgICAgICAgICAgICAnKic6ICAndGV4dC9qYXZhc2NyaXB0LCB0ZXh0L2h0bWwsIGFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWwsICovKidcbiAgICAgICAgICAgICwgJ3htbCc6ICAnYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbCdcbiAgICAgICAgICAgICwgJ2h0bWwnOiAndGV4dC9odG1sJ1xuICAgICAgICAgICAgLCAndGV4dCc6ICd0ZXh0L3BsYWluJ1xuICAgICAgICAgICAgLCAnanNvbic6ICdhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQnXG4gICAgICAgICAgICAsICdqcyc6ICAgJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQsIHRleHQvamF2YXNjcmlwdCdcbiAgICAgICAgICB9XG4gICAgICB9XG5cbiAgICAsIHhociA9IGZ1bmN0aW9uKG8pIHtcbiAgICAgICAgLy8gaXMgaXQgeC1kb21haW5cbiAgICAgICAgaWYgKG9bJ2Nyb3NzT3JpZ2luJ10gPT09IHRydWUpIHtcbiAgICAgICAgICB2YXIgeGhyID0gd2luW3htbEh0dHBSZXF1ZXN0XSA/IG5ldyBYTUxIdHRwUmVxdWVzdCgpIDogbnVsbFxuICAgICAgICAgIGlmICh4aHIgJiYgJ3dpdGhDcmVkZW50aWFscycgaW4geGhyKSB7XG4gICAgICAgICAgICByZXR1cm4geGhyXG4gICAgICAgICAgfSBlbHNlIGlmICh3aW5beERvbWFpblJlcXVlc3RdKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFhEb21haW5SZXF1ZXN0KClcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdCcm93c2VyIGRvZXMgbm90IHN1cHBvcnQgY3Jvc3Mtb3JpZ2luIHJlcXVlc3RzJylcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAod2luW3htbEh0dHBSZXF1ZXN0XSkge1xuICAgICAgICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTWljcm9zb2Z0LlhNTEhUVFAnKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgLCBnbG9iYWxTZXR1cE9wdGlvbnMgPSB7XG4gICAgICAgIGRhdGFGaWx0ZXI6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgcmV0dXJuIGRhdGFcbiAgICAgICAgfVxuICAgICAgfVxuXG4gIGZ1bmN0aW9uIHN1Y2NlZWQocikge1xuICAgIHZhciBwcm90b2NvbCA9IHByb3RvY29sUmUuZXhlYyhyLnVybCk7XG4gICAgcHJvdG9jb2wgPSAocHJvdG9jb2wgJiYgcHJvdG9jb2xbMV0pIHx8IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbDtcbiAgICByZXR1cm4gaHR0cHNSZS50ZXN0KHByb3RvY29sKSA/IHR3b0h1bmRvLnRlc3Qoci5yZXF1ZXN0LnN0YXR1cykgOiAhIXIucmVxdWVzdC5yZXNwb25zZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVJlYWR5U3RhdGUociwgc3VjY2VzcywgZXJyb3IpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgLy8gdXNlIF9hYm9ydGVkIHRvIG1pdGlnYXRlIGFnYWluc3QgSUUgZXJyIGMwMGMwMjNmXG4gICAgICAvLyAoY2FuJ3QgcmVhZCBwcm9wcyBvbiBhYm9ydGVkIHJlcXVlc3Qgb2JqZWN0cylcbiAgICAgIGlmIChyLl9hYm9ydGVkKSByZXR1cm4gZXJyb3Ioci5yZXF1ZXN0KVxuICAgICAgaWYgKHIuX3RpbWVkT3V0KSByZXR1cm4gZXJyb3Ioci5yZXF1ZXN0LCAnUmVxdWVzdCBpcyBhYm9ydGVkOiB0aW1lb3V0JylcbiAgICAgIGlmIChyLnJlcXVlc3QgJiYgci5yZXF1ZXN0W3JlYWR5U3RhdGVdID09IDQpIHtcbiAgICAgICAgci5yZXF1ZXN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IG5vb3BcbiAgICAgICAgaWYgKHN1Y2NlZWQocikpIHN1Y2Nlc3Moci5yZXF1ZXN0KVxuICAgICAgICBlbHNlXG4gICAgICAgICAgZXJyb3Ioci5yZXF1ZXN0KVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldEhlYWRlcnMoaHR0cCwgbykge1xuICAgIHZhciBoZWFkZXJzID0gb1snaGVhZGVycyddIHx8IHt9XG4gICAgICAsIGhcblxuICAgIGhlYWRlcnNbJ0FjY2VwdCddID0gaGVhZGVyc1snQWNjZXB0J11cbiAgICAgIHx8IGRlZmF1bHRIZWFkZXJzWydhY2NlcHQnXVtvWyd0eXBlJ11dXG4gICAgICB8fCBkZWZhdWx0SGVhZGVyc1snYWNjZXB0J11bJyonXVxuXG4gICAgdmFyIGlzQUZvcm1EYXRhID0gdHlwZW9mIEZvcm1EYXRhID09PSAnZnVuY3Rpb24nICYmIChvWydkYXRhJ10gaW5zdGFuY2VvZiBGb3JtRGF0YSk7XG4gICAgLy8gYnJlYWtzIGNyb3NzLW9yaWdpbiByZXF1ZXN0cyB3aXRoIGxlZ2FjeSBicm93c2Vyc1xuICAgIGlmICghb1snY3Jvc3NPcmlnaW4nXSAmJiAhaGVhZGVyc1tyZXF1ZXN0ZWRXaXRoXSkgaGVhZGVyc1tyZXF1ZXN0ZWRXaXRoXSA9IGRlZmF1bHRIZWFkZXJzWydyZXF1ZXN0ZWRXaXRoJ11cbiAgICBpZiAoIWhlYWRlcnNbY29udGVudFR5cGVdICYmICFpc0FGb3JtRGF0YSkgaGVhZGVyc1tjb250ZW50VHlwZV0gPSBvWydjb250ZW50VHlwZSddIHx8IGRlZmF1bHRIZWFkZXJzWydjb250ZW50VHlwZSddXG4gICAgZm9yIChoIGluIGhlYWRlcnMpXG4gICAgICBoZWFkZXJzLmhhc093blByb3BlcnR5KGgpICYmICdzZXRSZXF1ZXN0SGVhZGVyJyBpbiBodHRwICYmIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihoLCBoZWFkZXJzW2hdKVxuICB9XG5cbiAgZnVuY3Rpb24gc2V0Q3JlZGVudGlhbHMoaHR0cCwgbykge1xuICAgIGlmICh0eXBlb2Ygb1snd2l0aENyZWRlbnRpYWxzJ10gIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBodHRwLndpdGhDcmVkZW50aWFscyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGh0dHAud2l0aENyZWRlbnRpYWxzID0gISFvWyd3aXRoQ3JlZGVudGlhbHMnXVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGdlbmVyYWxDYWxsYmFjayhkYXRhKSB7XG4gICAgbGFzdFZhbHVlID0gZGF0YVxuICB9XG5cbiAgZnVuY3Rpb24gdXJsYXBwZW5kICh1cmwsIHMpIHtcbiAgICByZXR1cm4gdXJsICsgKC9cXD8vLnRlc3QodXJsKSA/ICcmJyA6ICc/JykgKyBzXG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVKc29ucChvLCBmbiwgZXJyLCB1cmwpIHtcbiAgICB2YXIgcmVxSWQgPSB1bmlxaWQrK1xuICAgICAgLCBjYmtleSA9IG9bJ2pzb25wQ2FsbGJhY2snXSB8fCAnY2FsbGJhY2snIC8vIHRoZSAnY2FsbGJhY2snIGtleVxuICAgICAgLCBjYnZhbCA9IG9bJ2pzb25wQ2FsbGJhY2tOYW1lJ10gfHwgcmVxd2VzdC5nZXRjYWxsYmFja1ByZWZpeChyZXFJZClcbiAgICAgICwgY2JyZWcgPSBuZXcgUmVnRXhwKCcoKF58XFxcXD98JiknICsgY2JrZXkgKyAnKT0oW14mXSspJylcbiAgICAgICwgbWF0Y2ggPSB1cmwubWF0Y2goY2JyZWcpXG4gICAgICAsIHNjcmlwdCA9IGRvYy5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKVxuICAgICAgLCBsb2FkZWQgPSAwXG4gICAgICAsIGlzSUUxMCA9IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignTVNJRSAxMC4wJykgIT09IC0xXG5cbiAgICBpZiAobWF0Y2gpIHtcbiAgICAgIGlmIChtYXRjaFszXSA9PT0gJz8nKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKGNicmVnLCAnJDE9JyArIGNidmFsKSAvLyB3aWxkY2FyZCBjYWxsYmFjayBmdW5jIG5hbWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNidmFsID0gbWF0Y2hbM10gLy8gcHJvdmlkZWQgY2FsbGJhY2sgZnVuYyBuYW1lXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHVybCA9IHVybGFwcGVuZCh1cmwsIGNia2V5ICsgJz0nICsgY2J2YWwpIC8vIG5vIGNhbGxiYWNrIGRldGFpbHMsIGFkZCAnZW1cbiAgICB9XG5cbiAgICB3aW5bY2J2YWxdID0gZ2VuZXJhbENhbGxiYWNrXG5cbiAgICBzY3JpcHQudHlwZSA9ICd0ZXh0L2phdmFzY3JpcHQnXG4gICAgc2NyaXB0LnNyYyA9IHVybFxuICAgIHNjcmlwdC5hc3luYyA9IHRydWVcbiAgICBpZiAodHlwZW9mIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgIT09ICd1bmRlZmluZWQnICYmICFpc0lFMTApIHtcbiAgICAgIC8vIG5lZWQgdGhpcyBmb3IgSUUgZHVlIHRvIG91dC1vZi1vcmRlciBvbnJlYWR5c3RhdGVjaGFuZ2UoKSwgYmluZGluZyBzY3JpcHRcbiAgICAgIC8vIGV4ZWN1dGlvbiB0byBhbiBldmVudCBsaXN0ZW5lciBnaXZlcyB1cyBjb250cm9sIG92ZXIgd2hlbiB0aGUgc2NyaXB0XG4gICAgICAvLyBpcyBleGVjdXRlZC4gU2VlIGh0dHA6Ly9qYXVib3VyZy5uZXQvMjAxMC8wNy9sb2FkaW5nLXNjcmlwdC1hcy1vbmNsaWNrLWhhbmRsZXItb2YuaHRtbFxuICAgICAgc2NyaXB0Lmh0bWxGb3IgPSBzY3JpcHQuaWQgPSAnX3JlcXdlc3RfJyArIHJlcUlkXG4gICAgfVxuXG4gICAgc2NyaXB0Lm9ubG9hZCA9IHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoKHNjcmlwdFtyZWFkeVN0YXRlXSAmJiBzY3JpcHRbcmVhZHlTdGF0ZV0gIT09ICdjb21wbGV0ZScgJiYgc2NyaXB0W3JlYWR5U3RhdGVdICE9PSAnbG9hZGVkJykgfHwgbG9hZGVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgc2NyaXB0Lm9ubG9hZCA9IHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsXG4gICAgICBzY3JpcHQub25jbGljayAmJiBzY3JpcHQub25jbGljaygpXG4gICAgICAvLyBDYWxsIHRoZSB1c2VyIGNhbGxiYWNrIHdpdGggdGhlIGxhc3QgdmFsdWUgc3RvcmVkIGFuZCBjbGVhbiB1cCB2YWx1ZXMgYW5kIHNjcmlwdHMuXG4gICAgICBmbihsYXN0VmFsdWUpXG4gICAgICBsYXN0VmFsdWUgPSB1bmRlZmluZWRcbiAgICAgIGhlYWQucmVtb3ZlQ2hpbGQoc2NyaXB0KVxuICAgICAgbG9hZGVkID0gMVxuICAgIH1cblxuICAgIC8vIEFkZCB0aGUgc2NyaXB0IHRvIHRoZSBET00gaGVhZFxuICAgIGhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KVxuXG4gICAgLy8gRW5hYmxlIEpTT05QIHRpbWVvdXRcbiAgICByZXR1cm4ge1xuICAgICAgYWJvcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2NyaXB0Lm9ubG9hZCA9IHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsXG4gICAgICAgIGVycih7fSwgJ1JlcXVlc3QgaXMgYWJvcnRlZDogdGltZW91dCcsIHt9KVxuICAgICAgICBsYXN0VmFsdWUgPSB1bmRlZmluZWRcbiAgICAgICAgaGVhZC5yZW1vdmVDaGlsZChzY3JpcHQpXG4gICAgICAgIGxvYWRlZCA9IDFcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnZXRSZXF1ZXN0KGZuLCBlcnIpIHtcbiAgICB2YXIgbyA9IHRoaXMub1xuICAgICAgLCBtZXRob2QgPSAob1snbWV0aG9kJ10gfHwgJ0dFVCcpLnRvVXBwZXJDYXNlKClcbiAgICAgICwgdXJsID0gdHlwZW9mIG8gPT09ICdzdHJpbmcnID8gbyA6IG9bJ3VybCddXG4gICAgICAvLyBjb252ZXJ0IG5vbi1zdHJpbmcgb2JqZWN0cyB0byBxdWVyeS1zdHJpbmcgZm9ybSB1bmxlc3Mgb1sncHJvY2Vzc0RhdGEnXSBpcyBmYWxzZVxuICAgICAgLCBkYXRhID0gKG9bJ3Byb2Nlc3NEYXRhJ10gIT09IGZhbHNlICYmIG9bJ2RhdGEnXSAmJiB0eXBlb2Ygb1snZGF0YSddICE9PSAnc3RyaW5nJylcbiAgICAgICAgPyByZXF3ZXN0LnRvUXVlcnlTdHJpbmcob1snZGF0YSddKVxuICAgICAgICA6IChvWydkYXRhJ10gfHwgbnVsbClcbiAgICAgICwgaHR0cFxuICAgICAgLCBzZW5kV2FpdCA9IGZhbHNlXG5cbiAgICAvLyBpZiB3ZSdyZSB3b3JraW5nIG9uIGEgR0VUIHJlcXVlc3QgYW5kIHdlIGhhdmUgZGF0YSB0aGVuIHdlIHNob3VsZCBhcHBlbmRcbiAgICAvLyBxdWVyeSBzdHJpbmcgdG8gZW5kIG9mIFVSTCBhbmQgbm90IHBvc3QgZGF0YVxuICAgIGlmICgob1sndHlwZSddID09ICdqc29ucCcgfHwgbWV0aG9kID09ICdHRVQnKSAmJiBkYXRhKSB7XG4gICAgICB1cmwgPSB1cmxhcHBlbmQodXJsLCBkYXRhKVxuICAgICAgZGF0YSA9IG51bGxcbiAgICB9XG5cbiAgICBpZiAob1sndHlwZSddID09ICdqc29ucCcpIHJldHVybiBoYW5kbGVKc29ucChvLCBmbiwgZXJyLCB1cmwpXG5cbiAgICAvLyBnZXQgdGhlIHhociBmcm9tIHRoZSBmYWN0b3J5IGlmIHBhc3NlZFxuICAgIC8vIGlmIHRoZSBmYWN0b3J5IHJldHVybnMgbnVsbCwgZmFsbC1iYWNrIHRvIG91cnNcbiAgICBodHRwID0gKG8ueGhyICYmIG8ueGhyKG8pKSB8fCB4aHIobylcblxuICAgIGh0dHAub3BlbihtZXRob2QsIHVybCwgb1snYXN5bmMnXSA9PT0gZmFsc2UgPyBmYWxzZSA6IHRydWUpXG4gICAgc2V0SGVhZGVycyhodHRwLCBvKVxuICAgIHNldENyZWRlbnRpYWxzKGh0dHAsIG8pXG4gICAgaWYgKHdpblt4RG9tYWluUmVxdWVzdF0gJiYgaHR0cCBpbnN0YW5jZW9mIHdpblt4RG9tYWluUmVxdWVzdF0pIHtcbiAgICAgICAgaHR0cC5vbmxvYWQgPSBmblxuICAgICAgICBodHRwLm9uZXJyb3IgPSBlcnJcbiAgICAgICAgLy8gTk9URTogc2VlXG4gICAgICAgIC8vIGh0dHA6Ly9zb2NpYWwubXNkbi5taWNyb3NvZnQuY29tL0ZvcnVtcy9lbi1VUy9pZXdlYmRldmVsb3BtZW50L3RocmVhZC8zMGVmM2FkZC03NjdjLTQ0MzYtYjhhOS1mMWNhMTliNDgxMmVcbiAgICAgICAgaHR0cC5vbnByb2dyZXNzID0gZnVuY3Rpb24oKSB7fVxuICAgICAgICBzZW5kV2FpdCA9IHRydWVcbiAgICB9IGVsc2Uge1xuICAgICAgaHR0cC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBoYW5kbGVSZWFkeVN0YXRlKHRoaXMsIGZuLCBlcnIpXG4gICAgfVxuICAgIG9bJ2JlZm9yZSddICYmIG9bJ2JlZm9yZSddKGh0dHApXG4gICAgaWYgKHNlbmRXYWl0KSB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaHR0cC5zZW5kKGRhdGEpXG4gICAgICB9LCAyMDApXG4gICAgfSBlbHNlIHtcbiAgICAgIGh0dHAuc2VuZChkYXRhKVxuICAgIH1cbiAgICByZXR1cm4gaHR0cFxuICB9XG5cbiAgZnVuY3Rpb24gUmVxd2VzdChvLCBmbikge1xuICAgIHRoaXMubyA9IG9cbiAgICB0aGlzLmZuID0gZm5cblxuICAgIGluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICB9XG5cbiAgZnVuY3Rpb24gc2V0VHlwZShoZWFkZXIpIHtcbiAgICAvLyBqc29uLCBqYXZhc2NyaXB0LCB0ZXh0L3BsYWluLCB0ZXh0L2h0bWwsIHhtbFxuICAgIGlmIChoZWFkZXIubWF0Y2goJ2pzb24nKSkgcmV0dXJuICdqc29uJ1xuICAgIGlmIChoZWFkZXIubWF0Y2goJ2phdmFzY3JpcHQnKSkgcmV0dXJuICdqcydcbiAgICBpZiAoaGVhZGVyLm1hdGNoKCd0ZXh0JykpIHJldHVybiAnaHRtbCdcbiAgICBpZiAoaGVhZGVyLm1hdGNoKCd4bWwnKSkgcmV0dXJuICd4bWwnXG4gIH1cblxuICBmdW5jdGlvbiBpbml0KG8sIGZuKSB7XG5cbiAgICB0aGlzLnVybCA9IHR5cGVvZiBvID09ICdzdHJpbmcnID8gbyA6IG9bJ3VybCddXG4gICAgdGhpcy50aW1lb3V0ID0gbnVsbFxuXG4gICAgLy8gd2hldGhlciByZXF1ZXN0IGhhcyBiZWVuIGZ1bGZpbGxlZCBmb3IgcHVycG9zZVxuICAgIC8vIG9mIHRyYWNraW5nIHRoZSBQcm9taXNlc1xuICAgIHRoaXMuX2Z1bGZpbGxlZCA9IGZhbHNlXG4gICAgLy8gc3VjY2VzcyBoYW5kbGVyc1xuICAgIHRoaXMuX3N1Y2Nlc3NIYW5kbGVyID0gZnVuY3Rpb24oKXt9XG4gICAgdGhpcy5fZnVsZmlsbG1lbnRIYW5kbGVycyA9IFtdXG4gICAgLy8gZXJyb3IgaGFuZGxlcnNcbiAgICB0aGlzLl9lcnJvckhhbmRsZXJzID0gW11cbiAgICAvLyBjb21wbGV0ZSAoYm90aCBzdWNjZXNzIGFuZCBmYWlsKSBoYW5kbGVyc1xuICAgIHRoaXMuX2NvbXBsZXRlSGFuZGxlcnMgPSBbXVxuICAgIHRoaXMuX2VycmVkID0gZmFsc2VcbiAgICB0aGlzLl9yZXNwb25zZUFyZ3MgPSB7fVxuXG4gICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICBmbiA9IGZuIHx8IGZ1bmN0aW9uICgpIHt9XG5cbiAgICBpZiAob1sndGltZW91dCddKSB7XG4gICAgICB0aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGltZWRPdXQoKVxuICAgICAgfSwgb1sndGltZW91dCddKVxuICAgIH1cblxuICAgIGlmIChvWydzdWNjZXNzJ10pIHtcbiAgICAgIHRoaXMuX3N1Y2Nlc3NIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBvWydzdWNjZXNzJ10uYXBwbHkobywgYXJndW1lbnRzKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvWydlcnJvciddKSB7XG4gICAgICB0aGlzLl9lcnJvckhhbmRsZXJzLnB1c2goZnVuY3Rpb24gKCkge1xuICAgICAgICBvWydlcnJvciddLmFwcGx5KG8sIGFyZ3VtZW50cylcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKG9bJ2NvbXBsZXRlJ10pIHtcbiAgICAgIHRoaXMuX2NvbXBsZXRlSGFuZGxlcnMucHVzaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG9bJ2NvbXBsZXRlJ10uYXBwbHkobywgYXJndW1lbnRzKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb21wbGV0ZSAocmVzcCkge1xuICAgICAgb1sndGltZW91dCddICYmIGNsZWFyVGltZW91dChzZWxmLnRpbWVvdXQpXG4gICAgICBzZWxmLnRpbWVvdXQgPSBudWxsXG4gICAgICB3aGlsZSAoc2VsZi5fY29tcGxldGVIYW5kbGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHNlbGYuX2NvbXBsZXRlSGFuZGxlcnMuc2hpZnQoKShyZXNwKVxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN1Y2Nlc3MgKHJlc3ApIHtcbiAgICAgIHZhciB0eXBlID0gb1sndHlwZSddIHx8IHJlc3AgJiYgc2V0VHlwZShyZXNwLmdldFJlc3BvbnNlSGVhZGVyKCdDb250ZW50LVR5cGUnKSkgLy8gcmVzcCBjYW4gYmUgdW5kZWZpbmVkIGluIElFXG4gICAgICByZXNwID0gKHR5cGUgIT09ICdqc29ucCcpID8gc2VsZi5yZXF1ZXN0IDogcmVzcFxuICAgICAgLy8gdXNlIGdsb2JhbCBkYXRhIGZpbHRlciBvbiByZXNwb25zZSB0ZXh0XG4gICAgICB2YXIgZmlsdGVyZWRSZXNwb25zZSA9IGdsb2JhbFNldHVwT3B0aW9ucy5kYXRhRmlsdGVyKHJlc3AucmVzcG9uc2VUZXh0LCB0eXBlKVxuICAgICAgICAsIHIgPSBmaWx0ZXJlZFJlc3BvbnNlXG4gICAgICB0cnkge1xuICAgICAgICByZXNwLnJlc3BvbnNlVGV4dCA9IHJcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gY2FuJ3QgYXNzaWduIHRoaXMgaW4gSUU8PTgsIGp1c3QgaWdub3JlXG4gICAgICB9XG4gICAgICBpZiAocikge1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAnanNvbic6XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3AgPSB3aW4uSlNPTiA/IHdpbi5KU09OLnBhcnNlKHIpIDogZXZhbCgnKCcgKyByICsgJyknKVxuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yKHJlc3AsICdDb3VsZCBub3QgcGFyc2UgSlNPTiBpbiByZXNwb25zZScsIGVycilcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnanMnOlxuICAgICAgICAgIHJlc3AgPSBldmFsKHIpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICAgICAgcmVzcCA9IHJcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICd4bWwnOlxuICAgICAgICAgIHJlc3AgPSByZXNwLnJlc3BvbnNlWE1MXG4gICAgICAgICAgICAgICYmIHJlc3AucmVzcG9uc2VYTUwucGFyc2VFcnJvciAvLyBJRSB0cm9sb2xvXG4gICAgICAgICAgICAgICYmIHJlc3AucmVzcG9uc2VYTUwucGFyc2VFcnJvci5lcnJvckNvZGVcbiAgICAgICAgICAgICAgJiYgcmVzcC5yZXNwb25zZVhNTC5wYXJzZUVycm9yLnJlYXNvblxuICAgICAgICAgICAgPyBudWxsXG4gICAgICAgICAgICA6IHJlc3AucmVzcG9uc2VYTUxcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHNlbGYuX3Jlc3BvbnNlQXJncy5yZXNwID0gcmVzcFxuICAgICAgc2VsZi5fZnVsZmlsbGVkID0gdHJ1ZVxuICAgICAgZm4ocmVzcClcbiAgICAgIHNlbGYuX3N1Y2Nlc3NIYW5kbGVyKHJlc3ApXG4gICAgICB3aGlsZSAoc2VsZi5fZnVsZmlsbG1lbnRIYW5kbGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlc3AgPSBzZWxmLl9mdWxmaWxsbWVudEhhbmRsZXJzLnNoaWZ0KCkocmVzcClcbiAgICAgIH1cblxuICAgICAgY29tcGxldGUocmVzcClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0aW1lZE91dCgpIHtcbiAgICAgIHNlbGYuX3RpbWVkT3V0ID0gdHJ1ZVxuICAgICAgc2VsZi5yZXF1ZXN0LmFib3J0KCkgICAgICBcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlcnJvcihyZXNwLCBtc2csIHQpIHtcbiAgICAgIHJlc3AgPSBzZWxmLnJlcXVlc3RcbiAgICAgIHNlbGYuX3Jlc3BvbnNlQXJncy5yZXNwID0gcmVzcFxuICAgICAgc2VsZi5fcmVzcG9uc2VBcmdzLm1zZyA9IG1zZ1xuICAgICAgc2VsZi5fcmVzcG9uc2VBcmdzLnQgPSB0XG4gICAgICBzZWxmLl9lcnJlZCA9IHRydWVcbiAgICAgIHdoaWxlIChzZWxmLl9lcnJvckhhbmRsZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc2VsZi5fZXJyb3JIYW5kbGVycy5zaGlmdCgpKHJlc3AsIG1zZywgdClcbiAgICAgIH1cbiAgICAgIGNvbXBsZXRlKHJlc3ApXG4gICAgfVxuXG4gICAgdGhpcy5yZXF1ZXN0ID0gZ2V0UmVxdWVzdC5jYWxsKHRoaXMsIHN1Y2Nlc3MsIGVycm9yKVxuICB9XG5cbiAgUmVxd2VzdC5wcm90b3R5cGUgPSB7XG4gICAgYWJvcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuX2Fib3J0ZWQgPSB0cnVlXG4gICAgICB0aGlzLnJlcXVlc3QuYWJvcnQoKVxuICAgIH1cblxuICAsIHJldHJ5OiBmdW5jdGlvbiAoKSB7XG4gICAgICBpbml0LmNhbGwodGhpcywgdGhpcy5vLCB0aGlzLmZuKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNtYWxsIGRldmlhdGlvbiBmcm9tIHRoZSBQcm9taXNlcyBBIENvbW1vbkpzIHNwZWNpZmljYXRpb25cbiAgICAgKiBodHRwOi8vd2lraS5jb21tb25qcy5vcmcvd2lraS9Qcm9taXNlcy9BXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBgdGhlbmAgd2lsbCBleGVjdXRlIHVwb24gc3VjY2Vzc2Z1bCByZXF1ZXN0c1xuICAgICAqL1xuICAsIHRoZW46IGZ1bmN0aW9uIChzdWNjZXNzLCBmYWlsKSB7XG4gICAgICBzdWNjZXNzID0gc3VjY2VzcyB8fCBmdW5jdGlvbiAoKSB7fVxuICAgICAgZmFpbCA9IGZhaWwgfHwgZnVuY3Rpb24gKCkge31cbiAgICAgIGlmICh0aGlzLl9mdWxmaWxsZWQpIHtcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VBcmdzLnJlc3AgPSBzdWNjZXNzKHRoaXMuX3Jlc3BvbnNlQXJncy5yZXNwKVxuICAgICAgfSBlbHNlIGlmICh0aGlzLl9lcnJlZCkge1xuICAgICAgICBmYWlsKHRoaXMuX3Jlc3BvbnNlQXJncy5yZXNwLCB0aGlzLl9yZXNwb25zZUFyZ3MubXNnLCB0aGlzLl9yZXNwb25zZUFyZ3MudClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2Z1bGZpbGxtZW50SGFuZGxlcnMucHVzaChzdWNjZXNzKVxuICAgICAgICB0aGlzLl9lcnJvckhhbmRsZXJzLnB1c2goZmFpbClcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogYGFsd2F5c2Agd2lsbCBleGVjdXRlIHdoZXRoZXIgdGhlIHJlcXVlc3Qgc3VjY2VlZHMgb3IgZmFpbHNcbiAgICAgKi9cbiAgLCBhbHdheXM6IGZ1bmN0aW9uIChmbikge1xuICAgICAgaWYgKHRoaXMuX2Z1bGZpbGxlZCB8fCB0aGlzLl9lcnJlZCkge1xuICAgICAgICBmbih0aGlzLl9yZXNwb25zZUFyZ3MucmVzcClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2NvbXBsZXRlSGFuZGxlcnMucHVzaChmbilcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogYGZhaWxgIHdpbGwgZXhlY3V0ZSB3aGVuIHRoZSByZXF1ZXN0IGZhaWxzXG4gICAgICovXG4gICwgZmFpbDogZnVuY3Rpb24gKGZuKSB7XG4gICAgICBpZiAodGhpcy5fZXJyZWQpIHtcbiAgICAgICAgZm4odGhpcy5fcmVzcG9uc2VBcmdzLnJlc3AsIHRoaXMuX3Jlc3BvbnNlQXJncy5tc2csIHRoaXMuX3Jlc3BvbnNlQXJncy50KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZXJyb3JIYW5kbGVycy5wdXNoKGZuKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG4gICwgJ2NhdGNoJzogZnVuY3Rpb24gKGZuKSB7XG4gICAgICByZXR1cm4gdGhpcy5mYWlsKGZuKVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcXdlc3QobywgZm4pIHtcbiAgICByZXR1cm4gbmV3IFJlcXdlc3QobywgZm4pXG4gIH1cblxuICAvLyBub3JtYWxpemUgbmV3bGluZSB2YXJpYW50cyBhY2NvcmRpbmcgdG8gc3BlYyAtPiBDUkxGXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZShzKSB7XG4gICAgcmV0dXJuIHMgPyBzLnJlcGxhY2UoL1xccj9cXG4vZywgJ1xcclxcbicpIDogJydcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlcmlhbChlbCwgY2IpIHtcbiAgICB2YXIgbiA9IGVsLm5hbWVcbiAgICAgICwgdCA9IGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKVxuICAgICAgLCBvcHRDYiA9IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICAgLy8gSUUgZ2l2ZXMgdmFsdWU9XCJcIiBldmVuIHdoZXJlIHRoZXJlIGlzIG5vIHZhbHVlIGF0dHJpYnV0ZVxuICAgICAgICAgIC8vICdzcGVjaWZpZWQnIHJlZjogaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9jb3JlLmh0bWwjSUQtODYyNTI5MjczXG4gICAgICAgICAgaWYgKG8gJiYgIW9bJ2Rpc2FibGVkJ10pXG4gICAgICAgICAgICBjYihuLCBub3JtYWxpemUob1snYXR0cmlidXRlcyddWyd2YWx1ZSddICYmIG9bJ2F0dHJpYnV0ZXMnXVsndmFsdWUnXVsnc3BlY2lmaWVkJ10gPyBvWyd2YWx1ZSddIDogb1sndGV4dCddKSlcbiAgICAgICAgfVxuICAgICAgLCBjaCwgcmEsIHZhbCwgaVxuXG4gICAgLy8gZG9uJ3Qgc2VyaWFsaXplIGVsZW1lbnRzIHRoYXQgYXJlIGRpc2FibGVkIG9yIHdpdGhvdXQgYSBuYW1lXG4gICAgaWYgKGVsLmRpc2FibGVkIHx8ICFuKSByZXR1cm5cblxuICAgIHN3aXRjaCAodCkge1xuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIGlmICghL3Jlc2V0fGJ1dHRvbnxpbWFnZXxmaWxlL2kudGVzdChlbC50eXBlKSkge1xuICAgICAgICBjaCA9IC9jaGVja2JveC9pLnRlc3QoZWwudHlwZSlcbiAgICAgICAgcmEgPSAvcmFkaW8vaS50ZXN0KGVsLnR5cGUpXG4gICAgICAgIHZhbCA9IGVsLnZhbHVlXG4gICAgICAgIC8vIFdlYktpdCBnaXZlcyB1cyBcIlwiIGluc3RlYWQgb2YgXCJvblwiIGlmIGEgY2hlY2tib3ggaGFzIG5vIHZhbHVlLCBzbyBjb3JyZWN0IGl0IGhlcmVcbiAgICAgICAgOyghKGNoIHx8IHJhKSB8fCBlbC5jaGVja2VkKSAmJiBjYihuLCBub3JtYWxpemUoY2ggJiYgdmFsID09PSAnJyA/ICdvbicgOiB2YWwpKVxuICAgICAgfVxuICAgICAgYnJlYWtcbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICBjYihuLCBub3JtYWxpemUoZWwudmFsdWUpKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgaWYgKGVsLnR5cGUudG9Mb3dlckNhc2UoKSA9PT0gJ3NlbGVjdC1vbmUnKSB7XG4gICAgICAgIG9wdENiKGVsLnNlbGVjdGVkSW5kZXggPj0gMCA/IGVsLm9wdGlvbnNbZWwuc2VsZWN0ZWRJbmRleF0gOiBudWxsKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpID0gMDsgZWwubGVuZ3RoICYmIGkgPCBlbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGVsLm9wdGlvbnNbaV0uc2VsZWN0ZWQgJiYgb3B0Q2IoZWwub3B0aW9uc1tpXSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICAvLyBjb2xsZWN0IHVwIGFsbCBmb3JtIGVsZW1lbnRzIGZvdW5kIGZyb20gdGhlIHBhc3NlZCBhcmd1bWVudCBlbGVtZW50cyBhbGxcbiAgLy8gdGhlIHdheSBkb3duIHRvIGNoaWxkIGVsZW1lbnRzOyBwYXNzIGEgJzxmb3JtPicgb3IgZm9ybSBmaWVsZHMuXG4gIC8vIGNhbGxlZCB3aXRoICd0aGlzJz1jYWxsYmFjayB0byB1c2UgZm9yIHNlcmlhbCgpIG9uIGVhY2ggZWxlbWVudFxuICBmdW5jdGlvbiBlYWNoRm9ybUVsZW1lbnQoKSB7XG4gICAgdmFyIGNiID0gdGhpc1xuICAgICAgLCBlLCBpXG4gICAgICAsIHNlcmlhbGl6ZVN1YnRhZ3MgPSBmdW5jdGlvbiAoZSwgdGFncykge1xuICAgICAgICAgIHZhciBpLCBqLCBmYVxuICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0YWdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBmYSA9IGVbYnlUYWddKHRhZ3NbaV0pXG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgZmEubGVuZ3RoOyBqKyspIHNlcmlhbChmYVtqXSwgY2IpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBlID0gYXJndW1lbnRzW2ldXG4gICAgICBpZiAoL2lucHV0fHNlbGVjdHx0ZXh0YXJlYS9pLnRlc3QoZS50YWdOYW1lKSkgc2VyaWFsKGUsIGNiKVxuICAgICAgc2VyaWFsaXplU3VidGFncyhlLCBbICdpbnB1dCcsICdzZWxlY3QnLCAndGV4dGFyZWEnIF0pXG4gICAgfVxuICB9XG5cbiAgLy8gc3RhbmRhcmQgcXVlcnkgc3RyaW5nIHN0eWxlIHNlcmlhbGl6YXRpb25cbiAgZnVuY3Rpb24gc2VyaWFsaXplUXVlcnlTdHJpbmcoKSB7XG4gICAgcmV0dXJuIHJlcXdlc3QudG9RdWVyeVN0cmluZyhyZXF3ZXN0LnNlcmlhbGl6ZUFycmF5LmFwcGx5KG51bGwsIGFyZ3VtZW50cykpXG4gIH1cblxuICAvLyB7ICduYW1lJzogJ3ZhbHVlJywgLi4uIH0gc3R5bGUgc2VyaWFsaXphdGlvblxuICBmdW5jdGlvbiBzZXJpYWxpemVIYXNoKCkge1xuICAgIHZhciBoYXNoID0ge31cbiAgICBlYWNoRm9ybUVsZW1lbnQuYXBwbHkoZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgICBpZiAobmFtZSBpbiBoYXNoKSB7XG4gICAgICAgIGhhc2hbbmFtZV0gJiYgIWlzQXJyYXkoaGFzaFtuYW1lXSkgJiYgKGhhc2hbbmFtZV0gPSBbaGFzaFtuYW1lXV0pXG4gICAgICAgIGhhc2hbbmFtZV0ucHVzaCh2YWx1ZSlcbiAgICAgIH0gZWxzZSBoYXNoW25hbWVdID0gdmFsdWVcbiAgICB9LCBhcmd1bWVudHMpXG4gICAgcmV0dXJuIGhhc2hcbiAgfVxuXG4gIC8vIFsgeyBuYW1lOiAnbmFtZScsIHZhbHVlOiAndmFsdWUnIH0sIC4uLiBdIHN0eWxlIHNlcmlhbGl6YXRpb25cbiAgcmVxd2VzdC5zZXJpYWxpemVBcnJheSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJyID0gW11cbiAgICBlYWNoRm9ybUVsZW1lbnQuYXBwbHkoZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgICBhcnIucHVzaCh7bmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlfSlcbiAgICB9LCBhcmd1bWVudHMpXG4gICAgcmV0dXJuIGFyclxuICB9XG5cbiAgcmVxd2VzdC5zZXJpYWxpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiAnJ1xuICAgIHZhciBvcHQsIGZuXG4gICAgICAsIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApXG5cbiAgICBvcHQgPSBhcmdzLnBvcCgpXG4gICAgb3B0ICYmIG9wdC5ub2RlVHlwZSAmJiBhcmdzLnB1c2gob3B0KSAmJiAob3B0ID0gbnVsbClcbiAgICBvcHQgJiYgKG9wdCA9IG9wdC50eXBlKVxuXG4gICAgaWYgKG9wdCA9PSAnbWFwJykgZm4gPSBzZXJpYWxpemVIYXNoXG4gICAgZWxzZSBpZiAob3B0ID09ICdhcnJheScpIGZuID0gcmVxd2VzdC5zZXJpYWxpemVBcnJheVxuICAgIGVsc2UgZm4gPSBzZXJpYWxpemVRdWVyeVN0cmluZ1xuXG4gICAgcmV0dXJuIGZuLmFwcGx5KG51bGwsIGFyZ3MpXG4gIH1cblxuICByZXF3ZXN0LnRvUXVlcnlTdHJpbmcgPSBmdW5jdGlvbiAobywgdHJhZCkge1xuICAgIHZhciBwcmVmaXgsIGlcbiAgICAgICwgdHJhZGl0aW9uYWwgPSB0cmFkIHx8IGZhbHNlXG4gICAgICAsIHMgPSBbXVxuICAgICAgLCBlbmMgPSBlbmNvZGVVUklDb21wb25lbnRcbiAgICAgICwgYWRkID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAvLyBJZiB2YWx1ZSBpcyBhIGZ1bmN0aW9uLCBpbnZva2UgaXQgYW5kIHJldHVybiBpdHMgdmFsdWVcbiAgICAgICAgICB2YWx1ZSA9ICgnZnVuY3Rpb24nID09PSB0eXBlb2YgdmFsdWUpID8gdmFsdWUoKSA6ICh2YWx1ZSA9PSBudWxsID8gJycgOiB2YWx1ZSlcbiAgICAgICAgICBzW3MubGVuZ3RoXSA9IGVuYyhrZXkpICsgJz0nICsgZW5jKHZhbHVlKVxuICAgICAgICB9XG4gICAgLy8gSWYgYW4gYXJyYXkgd2FzIHBhc3NlZCBpbiwgYXNzdW1lIHRoYXQgaXQgaXMgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cy5cbiAgICBpZiAoaXNBcnJheShvKSkge1xuICAgICAgZm9yIChpID0gMDsgbyAmJiBpIDwgby5sZW5ndGg7IGkrKykgYWRkKG9baV1bJ25hbWUnXSwgb1tpXVsndmFsdWUnXSlcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgdHJhZGl0aW9uYWwsIGVuY29kZSB0aGUgXCJvbGRcIiB3YXkgKHRoZSB3YXkgMS4zLjIgb3Igb2xkZXJcbiAgICAgIC8vIGRpZCBpdCksIG90aGVyd2lzZSBlbmNvZGUgcGFyYW1zIHJlY3Vyc2l2ZWx5LlxuICAgICAgZm9yIChwcmVmaXggaW4gbykge1xuICAgICAgICBpZiAoby5oYXNPd25Qcm9wZXJ0eShwcmVmaXgpKSBidWlsZFBhcmFtcyhwcmVmaXgsIG9bcHJlZml4XSwgdHJhZGl0aW9uYWwsIGFkZClcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzcGFjZXMgc2hvdWxkIGJlICsgYWNjb3JkaW5nIHRvIHNwZWNcbiAgICByZXR1cm4gcy5qb2luKCcmJykucmVwbGFjZSgvJTIwL2csICcrJylcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkUGFyYW1zKHByZWZpeCwgb2JqLCB0cmFkaXRpb25hbCwgYWRkKSB7XG4gICAgdmFyIG5hbWUsIGksIHZcbiAgICAgICwgcmJyYWNrZXQgPSAvXFxbXFxdJC9cblxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgIC8vIFNlcmlhbGl6ZSBhcnJheSBpdGVtLlxuICAgICAgZm9yIChpID0gMDsgb2JqICYmIGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdiA9IG9ialtpXVxuICAgICAgICBpZiAodHJhZGl0aW9uYWwgfHwgcmJyYWNrZXQudGVzdChwcmVmaXgpKSB7XG4gICAgICAgICAgLy8gVHJlYXQgZWFjaCBhcnJheSBpdGVtIGFzIGEgc2NhbGFyLlxuICAgICAgICAgIGFkZChwcmVmaXgsIHYpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYnVpbGRQYXJhbXMocHJlZml4ICsgJ1snICsgKHR5cGVvZiB2ID09PSAnb2JqZWN0JyA/IGkgOiAnJykgKyAnXScsIHYsIHRyYWRpdGlvbmFsLCBhZGQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iaiAmJiBvYmoudG9TdHJpbmcoKSA9PT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIC8vIFNlcmlhbGl6ZSBvYmplY3QgaXRlbS5cbiAgICAgIGZvciAobmFtZSBpbiBvYmopIHtcbiAgICAgICAgYnVpbGRQYXJhbXMocHJlZml4ICsgJ1snICsgbmFtZSArICddJywgb2JqW25hbWVdLCB0cmFkaXRpb25hbCwgYWRkKVxuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNlcmlhbGl6ZSBzY2FsYXIgaXRlbS5cbiAgICAgIGFkZChwcmVmaXgsIG9iailcbiAgICB9XG4gIH1cblxuICByZXF3ZXN0LmdldGNhbGxiYWNrUHJlZml4ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBjYWxsYmFja1ByZWZpeFxuICB9XG5cbiAgLy8galF1ZXJ5IGFuZCBaZXB0byBjb21wYXRpYmlsaXR5LCBkaWZmZXJlbmNlcyBjYW4gYmUgcmVtYXBwZWQgaGVyZSBzbyB5b3UgY2FuIGNhbGxcbiAgLy8gLmFqYXguY29tcGF0KG9wdGlvbnMsIGNhbGxiYWNrKVxuICByZXF3ZXN0LmNvbXBhdCA9IGZ1bmN0aW9uIChvLCBmbikge1xuICAgIGlmIChvKSB7XG4gICAgICBvWyd0eXBlJ10gJiYgKG9bJ21ldGhvZCddID0gb1sndHlwZSddKSAmJiBkZWxldGUgb1sndHlwZSddXG4gICAgICBvWydkYXRhVHlwZSddICYmIChvWyd0eXBlJ10gPSBvWydkYXRhVHlwZSddKVxuICAgICAgb1snanNvbnBDYWxsYmFjayddICYmIChvWydqc29ucENhbGxiYWNrTmFtZSddID0gb1snanNvbnBDYWxsYmFjayddKSAmJiBkZWxldGUgb1snanNvbnBDYWxsYmFjayddXG4gICAgICBvWydqc29ucCddICYmIChvWydqc29ucENhbGxiYWNrJ10gPSBvWydqc29ucCddKVxuICAgIH1cbiAgICByZXR1cm4gbmV3IFJlcXdlc3QobywgZm4pXG4gIH1cblxuICByZXF3ZXN0LmFqYXhTZXR1cCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgICBmb3IgKHZhciBrIGluIG9wdGlvbnMpIHtcbiAgICAgIGdsb2JhbFNldHVwT3B0aW9uc1trXSA9IG9wdGlvbnNba11cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVxd2VzdFxufSk7XG4iLCIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxMS0yMDE0IEZlbGl4IEduYXNzXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqL1xuKGZ1bmN0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblxuICAvKiBDb21tb25KUyAqL1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcpICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKVxuXG4gIC8qIEFNRCBtb2R1bGUgKi9cbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIGRlZmluZShmYWN0b3J5KVxuXG4gIC8qIEJyb3dzZXIgZ2xvYmFsICovXG4gIGVsc2Ugcm9vdC5TcGlubmVyID0gZmFjdG9yeSgpXG59XG4odGhpcywgZnVuY3Rpb24oKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIHZhciBwcmVmaXhlcyA9IFsnd2Via2l0JywgJ01veicsICdtcycsICdPJ10gLyogVmVuZG9yIHByZWZpeGVzICovXG4gICAgLCBhbmltYXRpb25zID0ge30gLyogQW5pbWF0aW9uIHJ1bGVzIGtleWVkIGJ5IHRoZWlyIG5hbWUgKi9cbiAgICAsIHVzZUNzc0FuaW1hdGlvbnMgLyogV2hldGhlciB0byB1c2UgQ1NTIGFuaW1hdGlvbnMgb3Igc2V0VGltZW91dCAqL1xuXG4gIC8qKlxuICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNyZWF0ZSBlbGVtZW50cy4gSWYgbm8gdGFnIG5hbWUgaXMgZ2l2ZW4sXG4gICAqIGEgRElWIGlzIGNyZWF0ZWQuIE9wdGlvbmFsbHkgcHJvcGVydGllcyBjYW4gYmUgcGFzc2VkLlxuICAgKi9cbiAgZnVuY3Rpb24gY3JlYXRlRWwodGFnLCBwcm9wKSB7XG4gICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcgfHwgJ2RpdicpXG4gICAgICAsIG5cblxuICAgIGZvcihuIGluIHByb3ApIGVsW25dID0gcHJvcFtuXVxuICAgIHJldHVybiBlbFxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgY2hpbGRyZW4gYW5kIHJldHVybnMgdGhlIHBhcmVudC5cbiAgICovXG4gIGZ1bmN0aW9uIGlucyhwYXJlbnQgLyogY2hpbGQxLCBjaGlsZDIsIC4uLiovKSB7XG4gICAgZm9yICh2YXIgaT0xLCBuPWFyZ3VtZW50cy5sZW5ndGg7IGk8bjsgaSsrKVxuICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGFyZ3VtZW50c1tpXSlcblxuICAgIHJldHVybiBwYXJlbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnQgYSBuZXcgc3R5bGVzaGVldCB0byBob2xkIHRoZSBAa2V5ZnJhbWUgb3IgVk1MIHJ1bGVzLlxuICAgKi9cbiAgdmFyIHNoZWV0ID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBlbCA9IGNyZWF0ZUVsKCdzdHlsZScsIHt0eXBlIDogJ3RleHQvY3NzJ30pXG4gICAgaW5zKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF0sIGVsKVxuICAgIHJldHVybiBlbC5zaGVldCB8fCBlbC5zdHlsZVNoZWV0XG4gIH0oKSlcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBvcGFjaXR5IGtleWZyYW1lIGFuaW1hdGlvbiBydWxlIGFuZCByZXR1cm5zIGl0cyBuYW1lLlxuICAgKiBTaW5jZSBtb3N0IG1vYmlsZSBXZWJraXRzIGhhdmUgdGltaW5nIGlzc3VlcyB3aXRoIGFuaW1hdGlvbi1kZWxheSxcbiAgICogd2UgY3JlYXRlIHNlcGFyYXRlIHJ1bGVzIGZvciBlYWNoIGxpbmUvc2VnbWVudC5cbiAgICovXG4gIGZ1bmN0aW9uIGFkZEFuaW1hdGlvbihhbHBoYSwgdHJhaWwsIGksIGxpbmVzKSB7XG4gICAgdmFyIG5hbWUgPSBbJ29wYWNpdHknLCB0cmFpbCwgfn4oYWxwaGEqMTAwKSwgaSwgbGluZXNdLmpvaW4oJy0nKVxuICAgICAgLCBzdGFydCA9IDAuMDEgKyBpL2xpbmVzICogMTAwXG4gICAgICAsIHogPSBNYXRoLm1heCgxIC0gKDEtYWxwaGEpIC8gdHJhaWwgKiAoMTAwLXN0YXJ0KSwgYWxwaGEpXG4gICAgICAsIHByZWZpeCA9IHVzZUNzc0FuaW1hdGlvbnMuc3Vic3RyaW5nKDAsIHVzZUNzc0FuaW1hdGlvbnMuaW5kZXhPZignQW5pbWF0aW9uJykpLnRvTG93ZXJDYXNlKClcbiAgICAgICwgcHJlID0gcHJlZml4ICYmICctJyArIHByZWZpeCArICctJyB8fCAnJ1xuXG4gICAgaWYgKCFhbmltYXRpb25zW25hbWVdKSB7XG4gICAgICBzaGVldC5pbnNlcnRSdWxlKFxuICAgICAgICAnQCcgKyBwcmUgKyAna2V5ZnJhbWVzICcgKyBuYW1lICsgJ3snICtcbiAgICAgICAgJzAle29wYWNpdHk6JyArIHogKyAnfScgK1xuICAgICAgICBzdGFydCArICcle29wYWNpdHk6JyArIGFscGhhICsgJ30nICtcbiAgICAgICAgKHN0YXJ0KzAuMDEpICsgJyV7b3BhY2l0eToxfScgK1xuICAgICAgICAoc3RhcnQrdHJhaWwpICUgMTAwICsgJyV7b3BhY2l0eTonICsgYWxwaGEgKyAnfScgK1xuICAgICAgICAnMTAwJXtvcGFjaXR5OicgKyB6ICsgJ30nICtcbiAgICAgICAgJ30nLCBzaGVldC5jc3NSdWxlcy5sZW5ndGgpXG5cbiAgICAgIGFuaW1hdGlvbnNbbmFtZV0gPSAxXG4gICAgfVxuXG4gICAgcmV0dXJuIG5hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmllcyB2YXJpb3VzIHZlbmRvciBwcmVmaXhlcyBhbmQgcmV0dXJucyB0aGUgZmlyc3Qgc3VwcG9ydGVkIHByb3BlcnR5LlxuICAgKi9cbiAgZnVuY3Rpb24gdmVuZG9yKGVsLCBwcm9wKSB7XG4gICAgdmFyIHMgPSBlbC5zdHlsZVxuICAgICAgLCBwcFxuICAgICAgLCBpXG5cbiAgICBwcm9wID0gcHJvcC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHByb3Auc2xpY2UoMSlcbiAgICBmb3IoaT0wOyBpPHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBwcCA9IHByZWZpeGVzW2ldK3Byb3BcbiAgICAgIGlmKHNbcHBdICE9PSB1bmRlZmluZWQpIHJldHVybiBwcFxuICAgIH1cbiAgICBpZihzW3Byb3BdICE9PSB1bmRlZmluZWQpIHJldHVybiBwcm9wXG4gIH1cblxuICAvKipcbiAgICogU2V0cyBtdWx0aXBsZSBzdHlsZSBwcm9wZXJ0aWVzIGF0IG9uY2UuXG4gICAqL1xuICBmdW5jdGlvbiBjc3MoZWwsIHByb3ApIHtcbiAgICBmb3IgKHZhciBuIGluIHByb3ApXG4gICAgICBlbC5zdHlsZVt2ZW5kb3IoZWwsIG4pfHxuXSA9IHByb3Bbbl1cblxuICAgIHJldHVybiBlbFxuICB9XG5cbiAgLyoqXG4gICAqIEZpbGxzIGluIGRlZmF1bHQgdmFsdWVzLlxuICAgKi9cbiAgZnVuY3Rpb24gbWVyZ2Uob2JqKSB7XG4gICAgZm9yICh2YXIgaT0xOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZGVmID0gYXJndW1lbnRzW2ldXG4gICAgICBmb3IgKHZhciBuIGluIGRlZilcbiAgICAgICAgaWYgKG9ialtuXSA9PT0gdW5kZWZpbmVkKSBvYmpbbl0gPSBkZWZbbl1cbiAgICB9XG4gICAgcmV0dXJuIG9ialxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGxpbmUgY29sb3IgZnJvbSB0aGUgZ2l2ZW4gc3RyaW5nIG9yIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gZ2V0Q29sb3IoY29sb3IsIGlkeCkge1xuICAgIHJldHVybiB0eXBlb2YgY29sb3IgPT0gJ3N0cmluZycgPyBjb2xvciA6IGNvbG9yW2lkeCAlIGNvbG9yLmxlbmd0aF1cbiAgfVxuXG4gIC8vIEJ1aWx0LWluIGRlZmF1bHRzXG5cbiAgdmFyIGRlZmF1bHRzID0ge1xuICAgIGxpbmVzOiAxMiwgICAgICAgICAgICAvLyBUaGUgbnVtYmVyIG9mIGxpbmVzIHRvIGRyYXdcbiAgICBsZW5ndGg6IDcsICAgICAgICAgICAgLy8gVGhlIGxlbmd0aCBvZiBlYWNoIGxpbmVcbiAgICB3aWR0aDogNSwgICAgICAgICAgICAgLy8gVGhlIGxpbmUgdGhpY2tuZXNzXG4gICAgcmFkaXVzOiAxMCwgICAgICAgICAgIC8vIFRoZSByYWRpdXMgb2YgdGhlIGlubmVyIGNpcmNsZVxuICAgIHJvdGF0ZTogMCwgICAgICAgICAgICAvLyBSb3RhdGlvbiBvZmZzZXRcbiAgICBjb3JuZXJzOiAxLCAgICAgICAgICAgLy8gUm91bmRuZXNzICgwLi4xKVxuICAgIGNvbG9yOiAnIzAwMCcsICAgICAgICAvLyAjcmdiIG9yICNycmdnYmJcbiAgICBkaXJlY3Rpb246IDEsICAgICAgICAgLy8gMTogY2xvY2t3aXNlLCAtMTogY291bnRlcmNsb2Nrd2lzZVxuICAgIHNwZWVkOiAxLCAgICAgICAgICAgICAvLyBSb3VuZHMgcGVyIHNlY29uZFxuICAgIHRyYWlsOiAxMDAsICAgICAgICAgICAvLyBBZnRlcmdsb3cgcGVyY2VudGFnZVxuICAgIG9wYWNpdHk6IDEvNCwgICAgICAgICAvLyBPcGFjaXR5IG9mIHRoZSBsaW5lc1xuICAgIGZwczogMjAsICAgICAgICAgICAgICAvLyBGcmFtZXMgcGVyIHNlY29uZCB3aGVuIHVzaW5nIHNldFRpbWVvdXQoKVxuICAgIHpJbmRleDogMmU5LCAgICAgICAgICAvLyBVc2UgYSBoaWdoIHotaW5kZXggYnkgZGVmYXVsdFxuICAgIGNsYXNzTmFtZTogJ3NwaW5uZXInLCAvLyBDU1MgY2xhc3MgdG8gYXNzaWduIHRvIHRoZSBlbGVtZW50XG4gICAgdG9wOiAnNTAlJywgICAgICAgICAgIC8vIGNlbnRlciB2ZXJ0aWNhbGx5XG4gICAgbGVmdDogJzUwJScsICAgICAgICAgIC8vIGNlbnRlciBob3Jpem9udGFsbHlcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyAgLy8gZWxlbWVudCBwb3NpdGlvblxuICB9XG5cbiAgLyoqIFRoZSBjb25zdHJ1Y3RvciAqL1xuICBmdW5jdGlvbiBTcGlubmVyKG8pIHtcbiAgICB0aGlzLm9wdHMgPSBtZXJnZShvIHx8IHt9LCBTcGlubmVyLmRlZmF1bHRzLCBkZWZhdWx0cylcbiAgfVxuXG4gIC8vIEdsb2JhbCBkZWZhdWx0cyB0aGF0IG92ZXJyaWRlIHRoZSBidWlsdC1pbnM6XG4gIFNwaW5uZXIuZGVmYXVsdHMgPSB7fVxuXG4gIG1lcmdlKFNwaW5uZXIucHJvdG90eXBlLCB7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIHRoZSBzcGlubmVyIHRvIHRoZSBnaXZlbiB0YXJnZXQgZWxlbWVudC4gSWYgdGhpcyBpbnN0YW5jZSBpcyBhbHJlYWR5XG4gICAgICogc3Bpbm5pbmcsIGl0IGlzIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCBmcm9tIGl0cyBwcmV2aW91cyB0YXJnZXQgYiBjYWxsaW5nXG4gICAgICogc3RvcCgpIGludGVybmFsbHkuXG4gICAgICovXG4gICAgc3BpbjogZnVuY3Rpb24odGFyZ2V0KSB7XG4gICAgICB0aGlzLnN0b3AoKVxuXG4gICAgICB2YXIgc2VsZiA9IHRoaXNcbiAgICAgICAgLCBvID0gc2VsZi5vcHRzXG4gICAgICAgICwgZWwgPSBzZWxmLmVsID0gY3NzKGNyZWF0ZUVsKDAsIHtjbGFzc05hbWU6IG8uY2xhc3NOYW1lfSksIHtwb3NpdGlvbjogby5wb3NpdGlvbiwgd2lkdGg6IDAsIHpJbmRleDogby56SW5kZXh9KVxuXG4gICAgICBjc3MoZWwsIHtcbiAgICAgICAgbGVmdDogby5sZWZ0LFxuICAgICAgICB0b3A6IG8udG9wXG4gICAgICB9KVxuICAgICAgICBcbiAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgdGFyZ2V0Lmluc2VydEJlZm9yZShlbCwgdGFyZ2V0LmZpcnN0Q2hpbGR8fG51bGwpXG4gICAgICB9XG5cbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgncm9sZScsICdwcm9ncmVzc2JhcicpXG4gICAgICBzZWxmLmxpbmVzKGVsLCBzZWxmLm9wdHMpXG5cbiAgICAgIGlmICghdXNlQ3NzQW5pbWF0aW9ucykge1xuICAgICAgICAvLyBObyBDU1MgYW5pbWF0aW9uIHN1cHBvcnQsIHVzZSBzZXRUaW1lb3V0KCkgaW5zdGVhZFxuICAgICAgICB2YXIgaSA9IDBcbiAgICAgICAgICAsIHN0YXJ0ID0gKG8ubGluZXMgLSAxKSAqICgxIC0gby5kaXJlY3Rpb24pIC8gMlxuICAgICAgICAgICwgYWxwaGFcbiAgICAgICAgICAsIGZwcyA9IG8uZnBzXG4gICAgICAgICAgLCBmID0gZnBzL28uc3BlZWRcbiAgICAgICAgICAsIG9zdGVwID0gKDEtby5vcGFjaXR5KSAvIChmKm8udHJhaWwgLyAxMDApXG4gICAgICAgICAgLCBhc3RlcCA9IGYvby5saW5lc1xuXG4gICAgICAgIDsoZnVuY3Rpb24gYW5pbSgpIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBvLmxpbmVzOyBqKyspIHtcbiAgICAgICAgICAgIGFscGhhID0gTWF0aC5tYXgoMSAtIChpICsgKG8ubGluZXMgLSBqKSAqIGFzdGVwKSAlIGYgKiBvc3RlcCwgby5vcGFjaXR5KVxuXG4gICAgICAgICAgICBzZWxmLm9wYWNpdHkoZWwsIGogKiBvLmRpcmVjdGlvbiArIHN0YXJ0LCBhbHBoYSwgbylcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VsZi50aW1lb3V0ID0gc2VsZi5lbCAmJiBzZXRUaW1lb3V0KGFuaW0sIH5+KDEwMDAvZnBzKSlcbiAgICAgICAgfSkoKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHNlbGZcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU3RvcHMgYW5kIHJlbW92ZXMgdGhlIFNwaW5uZXIuXG4gICAgICovXG4gICAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZWwgPSB0aGlzLmVsXG4gICAgICBpZiAoZWwpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dClcbiAgICAgICAgaWYgKGVsLnBhcmVudE5vZGUpIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpXG4gICAgICAgIHRoaXMuZWwgPSB1bmRlZmluZWRcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB0aGF0IGRyYXdzIHRoZSBpbmRpdmlkdWFsIGxpbmVzLiBXaWxsIGJlIG92ZXJ3cml0dGVuXG4gICAgICogaW4gVk1MIGZhbGxiYWNrIG1vZGUgYmVsb3cuXG4gICAgICovXG4gICAgbGluZXM6IGZ1bmN0aW9uKGVsLCBvKSB7XG4gICAgICB2YXIgaSA9IDBcbiAgICAgICAgLCBzdGFydCA9IChvLmxpbmVzIC0gMSkgKiAoMSAtIG8uZGlyZWN0aW9uKSAvIDJcbiAgICAgICAgLCBzZWdcblxuICAgICAgZnVuY3Rpb24gZmlsbChjb2xvciwgc2hhZG93KSB7XG4gICAgICAgIHJldHVybiBjc3MoY3JlYXRlRWwoKSwge1xuICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgIHdpZHRoOiAoby5sZW5ndGgrby53aWR0aCkgKyAncHgnLFxuICAgICAgICAgIGhlaWdodDogby53aWR0aCArICdweCcsXG4gICAgICAgICAgYmFja2dyb3VuZDogY29sb3IsXG4gICAgICAgICAgYm94U2hhZG93OiBzaGFkb3csXG4gICAgICAgICAgdHJhbnNmb3JtT3JpZ2luOiAnbGVmdCcsXG4gICAgICAgICAgdHJhbnNmb3JtOiAncm90YXRlKCcgKyB+figzNjAvby5saW5lcyppK28ucm90YXRlKSArICdkZWcpIHRyYW5zbGF0ZSgnICsgby5yYWRpdXMrJ3B4JyArJywwKScsXG4gICAgICAgICAgYm9yZGVyUmFkaXVzOiAoby5jb3JuZXJzICogby53aWR0aD4+MSkgKyAncHgnXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGZvciAoOyBpIDwgby5saW5lczsgaSsrKSB7XG4gICAgICAgIHNlZyA9IGNzcyhjcmVhdGVFbCgpLCB7XG4gICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgdG9wOiAxK34oby53aWR0aC8yKSArICdweCcsXG4gICAgICAgICAgdHJhbnNmb3JtOiBvLmh3YWNjZWwgPyAndHJhbnNsYXRlM2QoMCwwLDApJyA6ICcnLFxuICAgICAgICAgIG9wYWNpdHk6IG8ub3BhY2l0eSxcbiAgICAgICAgICBhbmltYXRpb246IHVzZUNzc0FuaW1hdGlvbnMgJiYgYWRkQW5pbWF0aW9uKG8ub3BhY2l0eSwgby50cmFpbCwgc3RhcnQgKyBpICogby5kaXJlY3Rpb24sIG8ubGluZXMpICsgJyAnICsgMS9vLnNwZWVkICsgJ3MgbGluZWFyIGluZmluaXRlJ1xuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChvLnNoYWRvdykgaW5zKHNlZywgY3NzKGZpbGwoJyMwMDAnLCAnMCAwIDRweCAnICsgJyMwMDAnKSwge3RvcDogMisncHgnfSkpXG4gICAgICAgIGlucyhlbCwgaW5zKHNlZywgZmlsbChnZXRDb2xvcihvLmNvbG9yLCBpKSwgJzAgMCAxcHggcmdiYSgwLDAsMCwuMSknKSkpXG4gICAgICB9XG4gICAgICByZXR1cm4gZWxcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgbWV0aG9kIHRoYXQgYWRqdXN0cyB0aGUgb3BhY2l0eSBvZiBhIHNpbmdsZSBsaW5lLlxuICAgICAqIFdpbGwgYmUgb3ZlcndyaXR0ZW4gaW4gVk1MIGZhbGxiYWNrIG1vZGUgYmVsb3cuXG4gICAgICovXG4gICAgb3BhY2l0eTogZnVuY3Rpb24oZWwsIGksIHZhbCkge1xuICAgICAgaWYgKGkgPCBlbC5jaGlsZE5vZGVzLmxlbmd0aCkgZWwuY2hpbGROb2Rlc1tpXS5zdHlsZS5vcGFjaXR5ID0gdmFsXG4gICAgfVxuXG4gIH0pXG5cblxuICBmdW5jdGlvbiBpbml0Vk1MKCkge1xuXG4gICAgLyogVXRpbGl0eSBmdW5jdGlvbiB0byBjcmVhdGUgYSBWTUwgdGFnICovXG4gICAgZnVuY3Rpb24gdm1sKHRhZywgYXR0cikge1xuICAgICAgcmV0dXJuIGNyZWF0ZUVsKCc8JyArIHRhZyArICcgeG1sbnM9XCJ1cm46c2NoZW1hcy1taWNyb3NvZnQuY29tOnZtbFwiIGNsYXNzPVwic3Bpbi12bWxcIj4nLCBhdHRyKVxuICAgIH1cblxuICAgIC8vIE5vIENTUyB0cmFuc2Zvcm1zIGJ1dCBWTUwgc3VwcG9ydCwgYWRkIGEgQ1NTIHJ1bGUgZm9yIFZNTCBlbGVtZW50czpcbiAgICBzaGVldC5hZGRSdWxlKCcuc3Bpbi12bWwnLCAnYmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTCknKVxuXG4gICAgU3Bpbm5lci5wcm90b3R5cGUubGluZXMgPSBmdW5jdGlvbihlbCwgbykge1xuICAgICAgdmFyIHIgPSBvLmxlbmd0aCtvLndpZHRoXG4gICAgICAgICwgcyA9IDIqclxuXG4gICAgICBmdW5jdGlvbiBncnAoKSB7XG4gICAgICAgIHJldHVybiBjc3MoXG4gICAgICAgICAgdm1sKCdncm91cCcsIHtcbiAgICAgICAgICAgIGNvb3Jkc2l6ZTogcyArICcgJyArIHMsXG4gICAgICAgICAgICBjb29yZG9yaWdpbjogLXIgKyAnICcgKyAtclxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgd2lkdGg6IHMsIGhlaWdodDogcyB9XG4gICAgICAgIClcbiAgICAgIH1cblxuICAgICAgdmFyIG1hcmdpbiA9IC0oby53aWR0aCtvLmxlbmd0aCkqMiArICdweCdcbiAgICAgICAgLCBnID0gY3NzKGdycCgpLCB7cG9zaXRpb246ICdhYnNvbHV0ZScsIHRvcDogbWFyZ2luLCBsZWZ0OiBtYXJnaW59KVxuICAgICAgICAsIGlcblxuICAgICAgZnVuY3Rpb24gc2VnKGksIGR4LCBmaWx0ZXIpIHtcbiAgICAgICAgaW5zKGcsXG4gICAgICAgICAgaW5zKGNzcyhncnAoKSwge3JvdGF0aW9uOiAzNjAgLyBvLmxpbmVzICogaSArICdkZWcnLCBsZWZ0OiB+fmR4fSksXG4gICAgICAgICAgICBpbnMoY3NzKHZtbCgncm91bmRyZWN0Jywge2FyY3NpemU6IG8uY29ybmVyc30pLCB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IHIsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBvLndpZHRoLFxuICAgICAgICAgICAgICAgIGxlZnQ6IG8ucmFkaXVzLFxuICAgICAgICAgICAgICAgIHRvcDogLW8ud2lkdGg+PjEsXG4gICAgICAgICAgICAgICAgZmlsdGVyOiBmaWx0ZXJcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIHZtbCgnZmlsbCcsIHtjb2xvcjogZ2V0Q29sb3Ioby5jb2xvciwgaSksIG9wYWNpdHk6IG8ub3BhY2l0eX0pLFxuICAgICAgICAgICAgICB2bWwoJ3N0cm9rZScsIHtvcGFjaXR5OiAwfSkgLy8gdHJhbnNwYXJlbnQgc3Ryb2tlIHRvIGZpeCBjb2xvciBibGVlZGluZyB1cG9uIG9wYWNpdHkgY2hhbmdlXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICB9XG5cbiAgICAgIGlmIChvLnNoYWRvdylcbiAgICAgICAgZm9yIChpID0gMTsgaSA8PSBvLmxpbmVzOyBpKyspXG4gICAgICAgICAgc2VnKGksIC0yLCAncHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LkJsdXIocGl4ZWxyYWRpdXM9MixtYWtlc2hhZG93PTEsc2hhZG93b3BhY2l0eT0uMyknKVxuXG4gICAgICBmb3IgKGkgPSAxOyBpIDw9IG8ubGluZXM7IGkrKykgc2VnKGkpXG4gICAgICByZXR1cm4gaW5zKGVsLCBnKVxuICAgIH1cblxuICAgIFNwaW5uZXIucHJvdG90eXBlLm9wYWNpdHkgPSBmdW5jdGlvbihlbCwgaSwgdmFsLCBvKSB7XG4gICAgICB2YXIgYyA9IGVsLmZpcnN0Q2hpbGRcbiAgICAgIG8gPSBvLnNoYWRvdyAmJiBvLmxpbmVzIHx8IDBcbiAgICAgIGlmIChjICYmIGkrbyA8IGMuY2hpbGROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgYyA9IGMuY2hpbGROb2Rlc1tpK29dOyBjID0gYyAmJiBjLmZpcnN0Q2hpbGQ7IGMgPSBjICYmIGMuZmlyc3RDaGlsZFxuICAgICAgICBpZiAoYykgYy5vcGFjaXR5ID0gdmFsXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHByb2JlID0gY3NzKGNyZWF0ZUVsKCdncm91cCcpLCB7YmVoYXZpb3I6ICd1cmwoI2RlZmF1bHQjVk1MKSd9KVxuXG4gIGlmICghdmVuZG9yKHByb2JlLCAndHJhbnNmb3JtJykgJiYgcHJvYmUuYWRqKSBpbml0Vk1MKClcbiAgZWxzZSB1c2VDc3NBbmltYXRpb25zID0gdmVuZG9yKHByb2JlLCAnYW5pbWF0aW9uJylcblxuICByZXR1cm4gU3Bpbm5lclxuXG59KSk7XG4iXX0= diff --git a/package.json b/package.json index 8600dac..d9aa580 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "wms-capabilities", "version": "0.3.2", "description": "WMS service Capabilities > JSON, based on openlayers ", - "main": "index.js", + "main": "dist/wms-capabilities.min.js", "bin": { "wmscapabilities": "bin/wmscapabilities" }, diff --git a/src/wms.js b/src/wms.js index dd216cd..3e577ea 100644 --- a/src/wms.js +++ b/src/wms.js @@ -155,6 +155,23 @@ WMS._readLatLonBoundingBox = function(node, objectStack) { }; +/** + * @privat + * @param {Node} node Node + * @param {Arra.} objectStack Object stack + * @return {Object} + */ +WMS._readScaleHint = function(node, objectStack) { + var min = parseFloat(node.getAttribute('min')); + var max = parseFloat(node.getAttribute('max')); + + return { + min: min, + max: max + }; +}; + + /** * @private * @param {Node} node Node. @@ -637,6 +654,7 @@ WMS.LAYER_PARSERS = XMLParser.makeParsersNS( 'Style': XMLParser.makeObjectPropertyPusher(WMS._readStyle), 'MinScaleDenominator': makePropertySetter(XSD.readDecimal), 'MaxScaleDenominator': makePropertySetter(XSD.readDecimal), + 'ScaleHint': makePropertySetter(WMS._readScaleHint), 'Layer': XMLParser.makeObjectPropertyPusher(WMS._readLayer) });